From abf124746df2375737ee370b689e4e97e03b6217 Mon Sep 17 00:00:00 2001 From: Matthew James Briggs Date: Thu, 21 May 2026 14:25:43 +0200 Subject: [PATCH 1/3] chore: delete vestigial files (DevNotes, OldCode, gen/version-a, gen/version-b) Historical files no longer needed: docs/DevNotes/ (old dev notes and XML diagrams), docs/OldCode/ (Enums.old.h/cpp), gen/version-a (original Ruby codegen scripts), gen/version-b (abandoned Rust codegen attempt). --- docs/DevNotes/Attribute Group Reference.xml | 27 - docs/DevNotes/CocoaNotes.txt | 17 - docs/DevNotes/Elements.h.order.csv | 589 --- docs/DevNotes/FourLayers.musx | Bin 86117 -> 0 bytes docs/DevNotes/FourLayers.png | Bin 199920 -> 0 bytes docs/DevNotes/FourLayers.xml | 150 - docs/DevNotes/FourLayersWithBackup.png | Bin 207463 -> 0 bytes docs/DevNotes/FourLayersWithBackup.xml | 153 - docs/DevNotes/GmMapToMusicXML.xml | 1761 -------- docs/DevNotes/IllogicalVoiceTags.png | Bin 220417 -> 0 bytes docs/DevNotes/IllogicalVoiceTags.xml | 153 - docs/DevNotes/MusicXML Standard Sounds.xml | 888 ---- docs/DevNotes/MusicXMLSounds.xml | 888 ---- docs/DevNotes/PerformanceNotes.txt | 40 - docs/DevNotes/StaffExperiment.xml | 155 - docs/DevNotes/TupletsTest.musx | Bin 89451 -> 0 bytes docs/DevNotes/TupletsTest.xml | 845 ---- docs/DevNotes/VoiceExperiment.xml | 155 - docs/OldCode/Enums.old.cpp | 3895 ----------------- docs/OldCode/Enums.old.h | 1324 ------ gen/version-a/ElementsOrder.xlsx | Bin 85020 -> 0 bytes gen/version-a/addStubs.rb | 0 gen/version-a/adjustElementsCpp.rb | 25 - gen/version-a/adjustElementsH.rb | 36 - gen/version-a/arrowGroup.rb | 130 - gen/version-a/attributes.rb | 310 -- gen/version-a/attributesLoop.rb | 22 - gen/version-a/beatUnitGroup.rb | 130 - gen/version-a/build-for-apple.sh | 212 - gen/version-a/choices.rb | 84 - gen/version-a/creditWordsGroup.rb | 131 - gen/version-a/cueNoteGroup.rb | 131 - gen/version-a/displayStepOctaveGroup.rb | 130 - gen/version-a/editorialGroup.rb | 130 - gen/version-a/editorialVoiceDirectionGroup.rb | 131 - gen/version-a/editorialVoiceGroup.rb | 131 - gen/version-a/elementsHUsingFile.rb | 28 - gen/version-a/elisionSyllabicGroup.rb | 130 - gen/version-a/elisionSyllabicTextGroup.rb | 130 - gen/version-a/findFilesWithBadCopyright.rb | 111 - gen/version-a/fromXElement.rb | 345 -- gen/version-a/fullNoteGroup.rb | 130 - gen/version-a/graceNoteGroup.rb | 131 - gen/version-a/groupCode.rb | 130 - gen/version-a/includeAlot.rb | 9 - gen/version-a/includeAttributesIfNeeded.rb | 12 - gen/version-a/includeEnumsIfNeeded.rb | 17 - gen/version-a/includeIfNeeded.rb | 20 - gen/version-a/includeStandaloneIfNeeded.rb | 16 - gen/version-a/isSymbolFound.rb | 5 - gen/version-a/layoutGroup.rb | 130 - gen/version-a/lineInstructionsH.rb | 132 - gen/version-a/listAttributeClasses.rb | 32 - gen/version-a/listClassesInEnumsH.rb | 22 - gen/version-a/listDecimals.rb | 39 - gen/version-a/listElementClasses.rb | 31 - gen/version-a/listEnums.rb | 27 - gen/version-a/listIntegers.rb | 39 - gen/version-a/listSpecialClasses.rb | 20 - gen/version-a/listStrings.rb | 39 - gen/version-a/midiDeviceInstrumentGroup.rb | 130 - gen/version-a/mxdeploy | 41 - gen/version-a/mxdeploy-v01.rb | 128 - gen/version-a/mxdeploy-v02.rb | 106 - gen/version-a/mxdeploy.rb | 239 - gen/version-a/note.rb | 143 - gen/version-a/parseElementsCpp.rb | 103 - gen/version-a/parseElementsH.rb | 129 - gen/version-a/parseElementsHOrder.rb | 37 - gen/version-a/parseXsd.rb | 9 - gen/version-a/smuflHeader.rb | 52 - gen/version-a/todo.txt | 23 - gen/version-a/version.rb | 17 - gen/version-a/writeElementsCppFiles.rb | 125 - gen/version-a/writeHFiles.rb | 199 - gen/version-b/.gitignore | 2 - gen/version-b/Cargo.lock | 705 --- gen/version-b/Cargo.toml | 33 - gen/version-b/rustfmt.toml | 2 - gen/version-b/src/bin/flatten.rs | 28 - gen/version-b/src/bin/main.rs | 16 - gen/version-b/src/bin/show.rs | 118 - gen/version-b/src/error.rs | 186 - gen/version-b/src/generate/compile_mx.rs | 49 - gen/version-b/src/generate/cpp/constants.rs | 168 - .../src/generate/cpp/cpp_template.rs | 90 - gen/version-b/src/generate/cpp/helpers.rs | 14 - gen/version-b/src/generate/cpp/mod.rs | 19 - gen/version-b/src/generate/cpp/modeler.rs | 357 -- .../src/generate/cpp/write_custom.rs | 43 - gen/version-b/src/generate/cpp/write_enums.rs | 188 - .../src/generate/cpp/write_numerics.rs | 323 -- .../src/generate/cpp/write_unions.rs | 589 --- gen/version-b/src/generate/cpp/writer.rs | 65 - .../generate/data/NumberOrNormal.cpp.template | 144 - .../generate/data/NumberOrNormal.h.template | 28 - .../data/PositiveIntegerOrEmpty.cpp.template | 147 - .../data/PositiveIntegerOrEmpty.h.template | 28 - .../src/generate/data/core.cpp.template | 11 - .../src/generate/data/core.h.template | 13 - .../data/decimal_builtins.cpp.template | 399 -- .../generate/data/decimal_builtins.h.template | 106 - .../generate/data/decimal_type.cpp.template | 11 - .../src/generate/data/decimal_type.h.template | 7 - .../src/generate/data/enum.cpp.template | 29 - .../src/generate/data/enum.h.template | 14 - .../generate/data/enum_wrapper.cpp.template | 82 - .../src/generate/data/enum_wrapper.h.template | 19 - .../data/integer_builtins.cpp.template | 80 - .../generate/data/integer_builtins.h.template | 39 - .../generate/data/integer_type.cpp.template | 11 - .../src/generate/data/integer_type.h.template | 7 - .../src/generate/data/union.cpp.template | 41 - .../src/generate/data/union.h.template | 19 - gen/version-b/src/generate/mod.rs | 45 - gen/version-b/src/generate/paths.rs | 62 - gen/version-b/src/generate/template.rs | 129 - gen/version-b/src/lib.rs | 14 - gen/version-b/src/model/builtin.rs | 22 - gen/version-b/src/model/create.rs | 91 - gen/version-b/src/model/creator.rs | 123 - .../src/model/default_create/enumeration.rs | 54 - gen/version-b/src/model/default_create/mod.rs | 61 - .../src/model/default_create/scalar.rs | 652 --- gen/version-b/src/model/enumeration.rs | 29 - gen/version-b/src/model/mod.rs | 115 - gen/version-b/src/model/post_process.rs | 12 - gen/version-b/src/model/scalar.rs | 98 - gen/version-b/src/model/symbol.rs | 126 - gen/version-b/src/model/transform.rs | 17 - gen/version-b/src/utils/mod.rs | 1 - gen/version-b/src/utils/string_stuff.rs | 627 --- gen/version-b/src/xsd/annotation.rs | 124 - gen/version-b/src/xsd/attribute.rs | 76 - gen/version-b/src/xsd/attribute_group.rs | 139 - gen/version-b/src/xsd/attributes.rs | 99 - gen/version-b/src/xsd/choice.rs | 132 - gen/version-b/src/xsd/common.rs | 56 - gen/version-b/src/xsd/complex_content.rs | 88 - gen/version-b/src/xsd/complex_type.rs | 359 -- gen/version-b/src/xsd/constants.rs | 72 - gen/version-b/src/xsd/element.rs | 244 -- gen/version-b/src/xsd/extension.rs | 98 - gen/version-b/src/xsd/group.rs | 217 - gen/version-b/src/xsd/id.rs | 271 -- gen/version-b/src/xsd/import.rs | 50 - gen/version-b/src/xsd/list.rs | 71 - gen/version-b/src/xsd/mod.rs | 389 -- gen/version-b/src/xsd/primitives.rs | 786 ---- gen/version-b/src/xsd/restriction.rs | 259 -- gen/version-b/src/xsd/sequence.rs | 123 - gen/version-b/src/xsd/simple_content.rs | 98 - gen/version-b/src/xsd/simple_type.rs | 199 - gen/version-b/src/xsd/union.rs | 82 - gen/version-b/src/xsd/utils.rs | 36 - gen/version-b/tests/xsd.rs | 9 - 156 files changed, 26564 deletions(-) delete mode 100644 docs/DevNotes/Attribute Group Reference.xml delete mode 100644 docs/DevNotes/CocoaNotes.txt delete mode 100755 docs/DevNotes/Elements.h.order.csv delete mode 100644 docs/DevNotes/FourLayers.musx delete mode 100644 docs/DevNotes/FourLayers.png delete mode 100644 docs/DevNotes/FourLayers.xml delete mode 100644 docs/DevNotes/FourLayersWithBackup.png delete mode 100644 docs/DevNotes/FourLayersWithBackup.xml delete mode 100644 docs/DevNotes/GmMapToMusicXML.xml delete mode 100644 docs/DevNotes/IllogicalVoiceTags.png delete mode 100644 docs/DevNotes/IllogicalVoiceTags.xml delete mode 100644 docs/DevNotes/MusicXML Standard Sounds.xml delete mode 100644 docs/DevNotes/MusicXMLSounds.xml delete mode 100644 docs/DevNotes/PerformanceNotes.txt delete mode 100644 docs/DevNotes/StaffExperiment.xml delete mode 100644 docs/DevNotes/TupletsTest.musx delete mode 100644 docs/DevNotes/TupletsTest.xml delete mode 100644 docs/DevNotes/VoiceExperiment.xml delete mode 100755 docs/OldCode/Enums.old.cpp delete mode 100755 docs/OldCode/Enums.old.h delete mode 100755 gen/version-a/ElementsOrder.xlsx delete mode 100755 gen/version-a/addStubs.rb delete mode 100755 gen/version-a/adjustElementsCpp.rb delete mode 100755 gen/version-a/adjustElementsH.rb delete mode 100755 gen/version-a/arrowGroup.rb delete mode 100755 gen/version-a/attributes.rb delete mode 100755 gen/version-a/attributesLoop.rb delete mode 100755 gen/version-a/beatUnitGroup.rb delete mode 100755 gen/version-a/build-for-apple.sh delete mode 100755 gen/version-a/choices.rb delete mode 100755 gen/version-a/creditWordsGroup.rb delete mode 100755 gen/version-a/cueNoteGroup.rb delete mode 100755 gen/version-a/displayStepOctaveGroup.rb delete mode 100755 gen/version-a/editorialGroup.rb delete mode 100755 gen/version-a/editorialVoiceDirectionGroup.rb delete mode 100755 gen/version-a/editorialVoiceGroup.rb delete mode 100755 gen/version-a/elementsHUsingFile.rb delete mode 100755 gen/version-a/elisionSyllabicGroup.rb delete mode 100755 gen/version-a/elisionSyllabicTextGroup.rb delete mode 100755 gen/version-a/findFilesWithBadCopyright.rb delete mode 100755 gen/version-a/fromXElement.rb delete mode 100755 gen/version-a/fullNoteGroup.rb delete mode 100755 gen/version-a/graceNoteGroup.rb delete mode 100755 gen/version-a/groupCode.rb delete mode 100755 gen/version-a/includeAlot.rb delete mode 100755 gen/version-a/includeAttributesIfNeeded.rb delete mode 100755 gen/version-a/includeEnumsIfNeeded.rb delete mode 100755 gen/version-a/includeIfNeeded.rb delete mode 100755 gen/version-a/includeStandaloneIfNeeded.rb delete mode 100755 gen/version-a/isSymbolFound.rb delete mode 100755 gen/version-a/layoutGroup.rb delete mode 100755 gen/version-a/lineInstructionsH.rb delete mode 100755 gen/version-a/listAttributeClasses.rb delete mode 100755 gen/version-a/listClassesInEnumsH.rb delete mode 100755 gen/version-a/listDecimals.rb delete mode 100755 gen/version-a/listElementClasses.rb delete mode 100755 gen/version-a/listEnums.rb delete mode 100755 gen/version-a/listIntegers.rb delete mode 100755 gen/version-a/listSpecialClasses.rb delete mode 100755 gen/version-a/listStrings.rb delete mode 100755 gen/version-a/midiDeviceInstrumentGroup.rb delete mode 100755 gen/version-a/mxdeploy delete mode 100644 gen/version-a/mxdeploy-v01.rb delete mode 100644 gen/version-a/mxdeploy-v02.rb delete mode 100644 gen/version-a/mxdeploy.rb delete mode 100755 gen/version-a/note.rb delete mode 100755 gen/version-a/parseElementsCpp.rb delete mode 100755 gen/version-a/parseElementsH.rb delete mode 100755 gen/version-a/parseElementsHOrder.rb delete mode 100644 gen/version-a/parseXsd.rb delete mode 100644 gen/version-a/smuflHeader.rb delete mode 100755 gen/version-a/todo.txt delete mode 100755 gen/version-a/version.rb delete mode 100755 gen/version-a/writeElementsCppFiles.rb delete mode 100755 gen/version-a/writeHFiles.rb delete mode 100644 gen/version-b/.gitignore delete mode 100644 gen/version-b/Cargo.lock delete mode 100644 gen/version-b/Cargo.toml delete mode 100644 gen/version-b/rustfmt.toml delete mode 100644 gen/version-b/src/bin/flatten.rs delete mode 100644 gen/version-b/src/bin/main.rs delete mode 100644 gen/version-b/src/bin/show.rs delete mode 100644 gen/version-b/src/error.rs delete mode 100644 gen/version-b/src/generate/compile_mx.rs delete mode 100644 gen/version-b/src/generate/cpp/constants.rs delete mode 100644 gen/version-b/src/generate/cpp/cpp_template.rs delete mode 100644 gen/version-b/src/generate/cpp/helpers.rs delete mode 100644 gen/version-b/src/generate/cpp/mod.rs delete mode 100644 gen/version-b/src/generate/cpp/modeler.rs delete mode 100644 gen/version-b/src/generate/cpp/write_custom.rs delete mode 100644 gen/version-b/src/generate/cpp/write_enums.rs delete mode 100644 gen/version-b/src/generate/cpp/write_numerics.rs delete mode 100644 gen/version-b/src/generate/cpp/write_unions.rs delete mode 100644 gen/version-b/src/generate/cpp/writer.rs delete mode 100644 gen/version-b/src/generate/data/NumberOrNormal.cpp.template delete mode 100644 gen/version-b/src/generate/data/NumberOrNormal.h.template delete mode 100644 gen/version-b/src/generate/data/PositiveIntegerOrEmpty.cpp.template delete mode 100644 gen/version-b/src/generate/data/PositiveIntegerOrEmpty.h.template delete mode 100644 gen/version-b/src/generate/data/core.cpp.template delete mode 100644 gen/version-b/src/generate/data/core.h.template delete mode 100644 gen/version-b/src/generate/data/decimal_builtins.cpp.template delete mode 100644 gen/version-b/src/generate/data/decimal_builtins.h.template delete mode 100644 gen/version-b/src/generate/data/decimal_type.cpp.template delete mode 100644 gen/version-b/src/generate/data/decimal_type.h.template delete mode 100644 gen/version-b/src/generate/data/enum.cpp.template delete mode 100644 gen/version-b/src/generate/data/enum.h.template delete mode 100644 gen/version-b/src/generate/data/enum_wrapper.cpp.template delete mode 100644 gen/version-b/src/generate/data/enum_wrapper.h.template delete mode 100644 gen/version-b/src/generate/data/integer_builtins.cpp.template delete mode 100644 gen/version-b/src/generate/data/integer_builtins.h.template delete mode 100644 gen/version-b/src/generate/data/integer_type.cpp.template delete mode 100644 gen/version-b/src/generate/data/integer_type.h.template delete mode 100644 gen/version-b/src/generate/data/union.cpp.template delete mode 100644 gen/version-b/src/generate/data/union.h.template delete mode 100644 gen/version-b/src/generate/mod.rs delete mode 100644 gen/version-b/src/generate/paths.rs delete mode 100644 gen/version-b/src/generate/template.rs delete mode 100644 gen/version-b/src/lib.rs delete mode 100644 gen/version-b/src/model/builtin.rs delete mode 100644 gen/version-b/src/model/create.rs delete mode 100644 gen/version-b/src/model/creator.rs delete mode 100644 gen/version-b/src/model/default_create/enumeration.rs delete mode 100644 gen/version-b/src/model/default_create/mod.rs delete mode 100644 gen/version-b/src/model/default_create/scalar.rs delete mode 100644 gen/version-b/src/model/enumeration.rs delete mode 100644 gen/version-b/src/model/mod.rs delete mode 100644 gen/version-b/src/model/post_process.rs delete mode 100644 gen/version-b/src/model/scalar.rs delete mode 100644 gen/version-b/src/model/symbol.rs delete mode 100644 gen/version-b/src/model/transform.rs delete mode 100644 gen/version-b/src/utils/mod.rs delete mode 100644 gen/version-b/src/utils/string_stuff.rs delete mode 100644 gen/version-b/src/xsd/annotation.rs delete mode 100644 gen/version-b/src/xsd/attribute.rs delete mode 100644 gen/version-b/src/xsd/attribute_group.rs delete mode 100644 gen/version-b/src/xsd/attributes.rs delete mode 100644 gen/version-b/src/xsd/choice.rs delete mode 100644 gen/version-b/src/xsd/common.rs delete mode 100644 gen/version-b/src/xsd/complex_content.rs delete mode 100644 gen/version-b/src/xsd/complex_type.rs delete mode 100644 gen/version-b/src/xsd/constants.rs delete mode 100644 gen/version-b/src/xsd/element.rs delete mode 100644 gen/version-b/src/xsd/extension.rs delete mode 100644 gen/version-b/src/xsd/group.rs delete mode 100644 gen/version-b/src/xsd/id.rs delete mode 100644 gen/version-b/src/xsd/import.rs delete mode 100644 gen/version-b/src/xsd/list.rs delete mode 100644 gen/version-b/src/xsd/mod.rs delete mode 100644 gen/version-b/src/xsd/primitives.rs delete mode 100644 gen/version-b/src/xsd/restriction.rs delete mode 100644 gen/version-b/src/xsd/sequence.rs delete mode 100644 gen/version-b/src/xsd/simple_content.rs delete mode 100644 gen/version-b/src/xsd/simple_type.rs delete mode 100644 gen/version-b/src/xsd/union.rs delete mode 100644 gen/version-b/src/xsd/utils.rs delete mode 100644 gen/version-b/tests/xsd.rs diff --git a/docs/DevNotes/Attribute Group Reference.xml b/docs/DevNotes/Attribute Group Reference.xml deleted file mode 100644 index 152455daa..000000000 --- a/docs/DevNotes/Attribute Group Reference.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/DevNotes/CocoaNotes.txt b/docs/DevNotes/CocoaNotes.txt deleted file mode 100644 index 2404abd3f..000000000 --- a/docs/DevNotes/CocoaNotes.txt +++ /dev/null @@ -1,17 +0,0 @@ -NSDocumentController -* Creates empty documents -* Creates documents from a file -* Tracks and manages those documents -* Handles document-related menu items, such as Open Recent - -NSDocument -* Manages display and capture its windows (using its window controllers) -* Reads and writes the persistent data associated with its document -* save, print, revert, and close -* Save and Page Setup dialogs -* owns and manages its window controllers -* manages its menu - -NSWindowController -* manages one window associated with a document -* assumes responsibility for closing windows properly diff --git a/docs/DevNotes/Elements.h.order.csv b/docs/DevNotes/Elements.h.order.csv deleted file mode 100755 index df782c304..000000000 --- a/docs/DevNotes/Elements.h.order.csv +++ /dev/null @@ -1,589 +0,0 @@ -1,DynamicsAttributes,AttributesInterface -2,Dynamics,ElementInterface -3,AccidentalTextAttributes,AttributesInterface -4,AccidentalText,ElementInterface -5,DisplayTextAttributes,AttributesInterface -6,DisplayText,ElementInterface -7,OtherPlayAttributes,AttributesInterface -8,OtherPlay,ElementInterface -9,PartSymbolAttributes,AttributesInterface -10,PartSymbol,ElementInterface -11,KeyOctaveAttributes,AttributesInterface -12,KeyOctave,ElementInterface -13,MultipleRestAttributes,AttributesInterface -14,MultipleRest,ElementInterface -15,MeasureRepeatAttributes,AttributesInterface -16,MeasureRepeat,ElementInterface -17,BarStyleAttributes,AttributesInterface -18,BarStyle,ElementInterface -19,FermataAttributes,AttributesInterface -20,Fermata,ElementInterface -21,EndingAttributes,AttributesInterface -22,Ending,ElementInterface -23,BassStepAttributes,AttributesInterface -24,BassStep,ElementInterface -25,BassAlterAttributes,AttributesInterface -26,BassAlter,ElementInterface -27,DegreeValueAttributes,AttributesInterface -28,DegreeValue,ElementInterface -29,DegreeAlterAttributes,AttributesInterface -30,DegreeAlter,ElementInterface -31,DegreeTypeAttributes,AttributesInterface -32,DegreeType,ElementInterface -33,OffsetAttributes,AttributesInterface -34,Offset,ElementInterface -35,RehearsalAttributes,AttributesInterface -36,Rehearsal,ElementInterface -37,WordsAttributes,AttributesInterface -38,Words,ElementInterface -39,PrincipalVoiceAttributes,AttributesInterface -40,PrincipalVoice,ElementInterface -41,OtherDirectionAttributes,AttributesInterface -42,OtherDirection,ElementInterface -43,FirstFretAttributes,AttributesInterface -44,FirstFret,ElementInterface -45,FretAttributes,AttributesInterface -46,Fret,ElementInterface -47,FingeringAttributes,AttributesInterface -48,Fingering,ElementInterface -49,FeatureAttributes,AttributesInterface -50,Feature,ElementInterface -51,PerMinuteAttributes,AttributesInterface -52,PerMinute,ElementInterface -53,MetronomeBeamAttributes,AttributesInterface -54,MetronomeBeam,ElementInterface -55,BeaterAttributes,AttributesInterface -56,Beater,ElementInterface -57,MeasureNumberingAttributes,AttributesInterface -58,MeasureNumbering,ElementInterface -59,RootStepAttributes,AttributesInterface -60,RootStep,ElementInterface -61,RootAlterAttributes,AttributesInterface -62,RootAlter,ElementInterface -63,MidiDeviceAttributes,AttributesInterface -64,MidiDevice,ElementInterface -65,EncoderAttributes,AttributesInterface -66,Encoder,ElementInterface -67,CreatorAttributes,AttributesInterface -68,Creator,ElementInterface -69,RightsAttributes,AttributesInterface -70,Rights,ElementInterface -71,RelationAttributes,AttributesInterface -72,Relation,ElementInterface -73,MiscellaneousFieldAttributes,AttributesInterface -74,MiscellaneousField,ElementInterface -75,LineWidthAttributes,AttributesInterface -76,LineWidth,ElementInterface -77,NoteSizeAttributes,AttributesInterface -78,NoteSize,ElementInterface -79,DistanceAttributes,AttributesInterface -80,Distance,ElementInterface -81,OtherAppearanceAttributes,AttributesInterface -82,OtherAppearance,ElementInterface -83,BreathMarkAttributes,AttributesInterface -84,BreathMark,ElementInterface -85,OtherArticulationAttributes,AttributesInterface -86,OtherArticulation,ElementInterface -87,WithBarAttributes,AttributesInterface -88,WithBar,ElementInterface -89,PrefixAttributes,AttributesInterface -90,Prefix,ElementInterface -91,FigureNumberAttributes,AttributesInterface -92,FigureNumber,ElementInterface -93,SuffixAttributes,AttributesInterface -94,Suffix,ElementInterface -95,HoleClosedAttributes,AttributesInterface -96,HoleClosed,ElementInterface -97,TextAttributes,AttributesInterface -98,Text,ElementInterface -99,ElisionAttributes,AttributesInterface -100,Elision,ElementInterface -101,GlissandoAttributes,AttributesInterface -102,Glissando,ElementInterface -103,SlideAttributes,AttributesInterface -104,Slide,ElementInterface -105,AccidentalMarkAttributes,AttributesInterface -106,AccidentalMark,ElementInterface -107,OtherNotationAttributes,AttributesInterface -108,OtherNotation,ElementInterface -109,TypeAttributes,AttributesInterface -110,Type,ElementInterface -111,AccidentalAttributes,AttributesInterface -112,Accidental,ElementInterface -113,StemAttributes,AttributesInterface -114,Stem,ElementInterface -115,NoteheadAttributes,AttributesInterface -116,Notehead,ElementInterface -117,BeamAttributes,AttributesInterface -118,Beam,ElementInterface -119,TremoloAttributes,AttributesInterface -120,Tremolo,ElementInterface -121,OtherOrnamentAttributes,AttributesInterface -122,OtherOrnament,ElementInterface -123,PluckAttributes,AttributesInterface -124,Pluck,ElementInterface -125,HammerOnAttributes,AttributesInterface -126,HammerOn,ElementInterface -127,PullOffAttributes,AttributesInterface -128,PullOff,ElementInterface -129,TapAttributes,AttributesInterface -130,Tap,ElementInterface -131,HandbellAttributes,AttributesInterface -132,Handbell,ElementInterface -133,OtherTechnicalAttributes,AttributesInterface -134,OtherTechnical,ElementInterface -135,TupletNumberAttributes,AttributesInterface -136,TupletNumber,ElementInterface -137,TupletTypeAttributes,AttributesInterface -138,TupletType,ElementInterface -139,CreditWordsAttributes,AttributesInterface -140,CreditWords,ElementInterface -141,GroupNameAttributes,AttributesInterface -142,GroupName,ElementInterface -143,GroupAbbreviationAttributes,AttributesInterface -144,GroupAbbreviation,ElementInterface -145,GroupSymbolAttributes,AttributesInterface -146,GroupSymbol,ElementInterface -147,GroupBarlineAttributes,AttributesInterface -148,GroupBarline,ElementInterface -149,PartNameAttributes,AttributesInterface -150,PartName,ElementInterface -151,PartAbbreviationAttributes,AttributesInterface -152,PartAbbreviation,ElementInterface -153,FootnoteAttributes,AttributesInterface -154,Footnote,ElementInterface -155,LevelAttributes,AttributesInterface -156,Level,ElementInterface -157,CancelAttributes,AttributesInterface -158,Cancel,ElementInterface -159,FunctionAttributes,AttributesInterface -160,Function,ElementInterface -161,KindAttributes,AttributesInterface -162,Kind,ElementInterface -163,InversionAttributes,AttributesInterface -164,Inversion,ElementInterface -165,MidiChannel,ElementInterface -166,MidiName,ElementInterface -167,MidiBank,ElementInterface -168,MidiProgram,ElementInterface -169,MidiUnpitched,ElementInterface -170,Volume,ElementInterface -171,Pan,ElementInterface -172,Elevation,ElementInterface -173,Ipa,ElementInterface -174,Mute,ElementInterface -175,SemiPitched,ElementInterface -176,Divisions,ElementInterface -177,Staves,ElementInterface -178,Instruments,ElementInterface -179,Sign,ElementInterface -180,Line,ElementInterface -181,ClefOctaveChange,ElementInterface -182,TimeRelation,ElementInterface -183,StaffType,ElementInterface -184,StaffLines,ElementInterface -185,Capo,ElementInterface -186,StaffSize,ElementInterface -187,SenzaMisura,ElementInterface -188,Diatonic,ElementInterface -189,Chromatic,ElementInterface -190,OctaveChange,ElementInterface -191,AccordionMiddle,ElementInterface -192,FrameStrings,ElementInterface -193,FrameFrets,ElementInterface -194,MetronomeRelation,ElementInterface -195,MetronomeType,ElementInterface -196,PedalStep,ElementInterface -197,PedalAlter,ElementInterface -198,Glass,ElementInterface -199,Metal,ElementInterface -200,Wood,ElementInterface -201,Pitched,ElementInterface -202,Membrane,ElementInterface -203,Effect,ElementInterface -204,StickLocation,ElementInterface -205,OtherPercussion,ElementInterface -206,StickType,ElementInterface -207,StickMaterial,ElementInterface -208,EncodingDate,ElementInterface -209,Software,ElementInterface -210,EncodingDescription,ElementInterface -211,Source,ElementInterface -212,MeasureDistance,ElementInterface -213,PageHeight,ElementInterface -214,PageWidth,ElementInterface -215,Millimeters,ElementInterface -216,Tenths,ElementInterface -217,StaffDistance,ElementInterface -218,SystemDistance,ElementInterface -219,TopSystemDistance,ElementInterface -220,ArrowDirection,ElementInterface -221,ArrowStyle,ElementInterface -222,CircularArrow,ElementInterface -223,BendAlter,ElementInterface -224,HoleType,ElementInterface -225,HoleShape,ElementInterface -226,Syllabic,ElementInterface -227,Step,ElementInterface -228,Alter,ElementInterface -229,Octave,ElementInterface -230,ActualNotes,ElementInterface -231,NormalNotes,ElementInterface -232,NormalType,ElementInterface -233,CreditType,ElementInterface -234,InstrumentName,ElementInterface -235,InstrumentAbbreviation,ElementInterface -236,InstrumentSound,ElementInterface -237,Ensemble,ElementInterface -238,Group,ElementInterface -239,VirtualLibrary,ElementInterface -240,VirtualName,ElementInterface -241,WorkNumber,ElementInterface -242,WorkTitle,ElementInterface -243,Staff,ElementInterface -244,TuningStep,ElementInterface -245,TuningAlter,ElementInterface -246,TuningOctave,ElementInterface -247,Voice,ElementInterface -248,KeyStep,ElementInterface -249,KeyAlter,ElementInterface -250,KeyAccidental,ElementInterface -251,SlashType,ElementInterface -252,Beats,ElementInterface -253,BeatType,ElementInterface -254,Fifths,ElementInterface -255,Mode,ElementInterface -256,BeatUnit,ElementInterface -257,TopMargin,ElementInterface -258,BottomMargin,ElementInterface -259,LeftMargin,ElementInterface -260,RightMargin,ElementInterface -261,Duration,ElementInterface -262,DisplayStep,ElementInterface -263,DisplayOctave,ElementInterface -264,MovementNumber,ElementInterface -265,MovementTitle,ElementInterface -266,Double,ElementInterface -267,AccordionHigh,ElementInterface -268,AccordionLow,ElementInterface -269,MetronomeDot,ElementInterface -270,Timpani,ElementInterface -271,PreBend,ElementInterface -272,Release,ElementInterface -273,Natural,ElementInterface -274,Artificial,ElementInterface -275,BasePitch,ElementInterface -276,TouchingPitch,ElementInterface -277,SoundingPitch,ElementInterface -278,Laughing,ElementInterface -279,Humming,ElementInterface -280,EndLine,ElementInterface -281,EndParagraph,ElementInterface -282,Cue,ElementInterface -283,NormalDot,ElementInterface -284,GroupTime,ElementInterface -285,Solo,ElementInterface -286,SlashDot,ElementInterface -287,BeatUnitDot,ElementInterface -288,Chord,ElementInterface -289,Segno,ElementInterface -290,Coda,ElementInterface -291,Damp,ElementInterface -292,DampAll,ElementInterface -293,Eyeglasses,ElementInterface -294,LeftDivider,ElementInterface -295,RightDivider,ElementInterface -296,EmptyPlacementAttributes,AttributesInterface -297,Accent,ElementInterface -298,Staccato,ElementInterface -299,Tenuto,ElementInterface -300,DetachedLegato,ElementInterface -301,Staccatissimo,ElementInterface -302,Spiccato,ElementInterface -303,EmptyLineAttributes,AttributesInterface -304,Scoop,ElementInterface -305,Plop,ElementInterface -306,Doit,ElementInterface -307,Falloff,ElementInterface -308,Caesura,ElementInterface -309,Stress,ElementInterface -310,Unstress,ElementInterface -311,Dot,ElementInterface -312,EmptyTrillSoundAttributes,AttributesInterface -313,TrillMark,ElementInterface -314,VerticalTurn,ElementInterface -315,Shake,ElementInterface -316,Schleifer,ElementInterface -317,UpBow,ElementInterface -318,DownBow,ElementInterface -319,OpenString,ElementInterface -320,ThumbPosition,ElementInterface -321,DoubleTongue,ElementInterface -322,TripleTongue,ElementInterface -323,Stopped,ElementInterface -324,SnapPizzicato,ElementInterface -325,Fingernails,ElementInterface -326,EmptyFontAttributes,AttributesInterface -327,MusicFont,ElementInterface -328,WordFont,ElementInterface -329,WavyLineAttributes,AttributesInterface -330,WavyLine,ElementInterface -331,RepeatAttributes,AttributesInterface -332,Repeat,ElementInterface -333,WedgeAttributes,AttributesInterface -334,Wedge,ElementInterface -335,DashesAttributes,AttributesInterface -336,Dashes,ElementInterface -337,BracketAttributes,AttributesInterface -338,Bracket,ElementInterface -339,PedalAttributes,AttributesInterface -340,Pedal,ElementInterface -341,OctaveShiftAttributes,AttributesInterface -342,OctaveShift,ElementInterface -343,StringMuteAttributes,AttributesInterface -344,StringMute,ElementInterface -345,ImageAttributes,AttributesInterface -346,Image,ElementInterface -347,BarreAttributes,AttributesInterface -348,Barre,ElementInterface -349,SupportsAttributes,AttributesInterface -350,Supports,ElementInterface -351,ExtendAttributes,AttributesInterface -352,Extend,ElementInterface -353,TiedAttributes,AttributesInterface -354,Tied,ElementInterface -355,SlurAttributes,AttributesInterface -356,Slur,ElementInterface -357,ArpeggiateAttributes,AttributesInterface -358,Arpeggiate,ElementInterface -359,NonArpeggiateAttributes,AttributesInterface -360,NonArpeggiate,ElementInterface -361,GraceAttributes,AttributesInterface -362,Grace,ElementInterface -363,TieAttributes,AttributesInterface -364,Tie,ElementInterface -365,InstrumentAttributes,AttributesInterface -366,Instrument,ElementInterface -367,TurnAttributes,AttributesInterface -368,Turn,ElementInterface -369,DelayedTurnAttributes,AttributesInterface -370,DelayedTurn,ElementInterface -371,InvertedTurnAttributes,AttributesInterface -372,InvertedTurn,ElementInterface -373,DelayedInvertedTurnAttributes,AttributesInterface -374,DelayedInvertedTurn,ElementInterface -375,TupletDotAttributes,AttributesInterface -376,TupletDot,ElementInterface -377,LinkAttributes,AttributesInterface -378,Link,ElementInterface -379,BookmarkAttributes,AttributesInterface -380,Bookmark,ElementInterface -381,CreditImageAttributes,AttributesInterface -382,CreditImage,ElementInterface -383,LyricFontAttributes,AttributesInterface -384,LyricFont,ElementInterface -385,LyricLanguageAttributes,AttributesInterface -386,LyricLanguage,ElementInterface -387,OpusAttributes,AttributesInterface -388,Opus,ElementInterface -389,TraditionalKey,ElementInterface -390,NonTraditionalKey,ElementInterface -391,KeyChoice,ElementInterface -392,KeyAttributes,AttributesInterface -393,Key,ElementInterface -394,ClefAttributes,AttributesInterface -395,Clef,ElementInterface -396,TransposeAttributes,AttributesInterface -397,Transpose,ElementInterface -398,DirectiveAttributes,AttributesInterface -399,Directive,ElementInterface -400,BeatRepeatAttributes,AttributesInterface -401,BeatRepeat,ElementInterface -402,SlashAttributes,AttributesInterface -403,Slash,ElementInterface -404,StaffTuningAttributes,AttributesInterface -405,StaffTuning,ElementInterface -406,StaffDetailsAttributes,AttributesInterface -407,StaffDetails,ElementInterface -408,MeasureStyleChoice,ElementInterface -409,MeasureStyleAttributes,AttributesInterface -410,MeasureStyle,ElementInterface -411,InterchangeableAttributes,AttributesInterface -412,Interchangeable,ElementInterface -413,AccordionRegistrationAttributes,AttributesInterface -414,AccordionRegistration,ElementInterface -415,TimeSignature,ElementInterface -416,TimeChoice,ElementInterface -417,TimeAttributes,AttributesInterface -418,Time,ElementInterface -419,StringAttributes,AttributesInterface -420,String,ElementInterface -421,FrameNote,ElementInterface -422,FrameAttributes,AttributesInterface -423,Frame,ElementInterface -424,PedalTuning,ElementInterface -425,HarpPedalsAttributes,AttributesInterface -426,HarpPedals,ElementInterface -427,TimeModificationNormalTypeNormalDot,ElementInterface -428,MetronomeTupletAttributes,AttributesInterface -429,MetronomeTuplet,ElementInterface -430,MetronomeNote,ElementInterface -431,BeatUnitGroup,ElementInterface -432,MetronomeRelationGroup,ElementInterface -433,NoteRelationNote,ElementInterface -434,PerMinuteOrBeatUnitChoice,ElementInterface -435,BeatUnitPer,ElementInterface -436,BeatUnitPerOrNoteRelationNoteChoice,ElementInterface -437,MetronomeAttributes,AttributesInterface -438,Metronome,ElementInterface -439,StickAttributes,AttributesInterface -440,Stick,ElementInterface -441,MeasureLayout,ElementInterface -442,DisplayTextOrAccidentalText,ElementInterface -443,PartNameDisplayAttributes,AttributesInterface -444,PartNameDisplay,ElementInterface -445,PercussionChoice,ElementInterface -446,PercussionAttributes,AttributesInterface -447,Percussion,ElementInterface -448,AccordAttributes,AttributesInterface -449,Accord,ElementInterface -450,Scordatura,ElementInterface -451,AttributesIterface,AttributesInterface -452,DirectionType,ElementInterface -453,MidiInstrumentAttributes,AttributesInterface -454,MidiInstrument,ElementInterface -455,PlayAttributes,AttributesInterface -456,Play,ElementInterface -457,Encoding,ElementInterface -458,Miscellaneous,ElementInterface -459,SoundAttributes,AttributesInterface -460,Sound,ElementInterface -461,PageMarginsAttributes,AttributesInterface -462,PageMargins,ElementInterface -463,SystemMargins,ElementInterface -464,SystemDividers,ElementInterface -465,StrongAccentAttributes,AttributesInterface -466,StrongAccent,ElementInterface -467,Figure,ElementInterface -468,NormalTypeNormalDotGroup,ElementInterface -469,TimeModification,ElementInterface -470,NoteheadText,ElementInterface -471,ArticulationsChoice,ElementInterface -472,Articulations,ElementInterface -473,ElisionSyllabicGroup,ElementInterface -474,ElisionSyllabicTextGroup,ElementInterface -475,SyllabicTextGroup,ElementInterface -476,LyricTextChoice,ElementInterface -477,EditorialGroup,ElementInterface -478,EditorialVoiceGroup,ElementInterface -479,LyricAttributes,AttributesInterface -480,Lyric,ElementInterface -481,MordentAttributes,AttributesInterface -482,Mordent,ElementInterface -483,InvertedMordentAttributes,AttributesInterface -484,InvertedMordent,ElementInterface -485,HeelAttributes,AttributesInterface -486,Heel,ElementInterface -487,ToeAttributes,AttributesInterface -488,Toe,ElementInterface -489,HoleAttributes,AttributesInterface -490,Hole,ElementInterface -491,TupletActual,ElementInterface -492,TupletNormal,ElementInterface -493,TupletAttributes,AttributesInterface -494,Tuplet,ElementInterface -495,Scaling,ElementInterface -496,Appearance,ElementInterface -497,VirtualInstrument,ElementInterface -498,Root,ElementInterface -499,Bass,ElementInterface -500,DegreeAttributes,AttributesInterface -501,Degree,ElementInterface -502,PageLayout,ElementInterface -503,SystemLayout,ElementInterface -504,StaffLayoutAttributes,AttributesInterface -505,StaffLayout,ElementInterface -506,Pitch,ElementInterface -507,DisplayStepOctaveGroup,ElementInterface -508,Unpitched,ElementInterface -509,RestAttributes,AttributesInterface -510,Rest,ElementInterface -511,Backup,ElementInterface -512,Forward,ElementInterface -513,FiguredBassAttributes,AttributesInterface -514,FiguredBass,ElementInterface -515,BarlineAttributes,AttributesInterface -516,Barline,ElementInterface -517,GroupingAttributes,AttributesInterface -518,Grouping,ElementInterface -519,Work,ElementInterface -520,LayoutGroup,ElementInterface -521,Defaults,ElementInterface -522,OrnamentsChoice,ElementInterface -523,Ornaments,ElementInterface -524,BendChoice,ElementInterface -525,BendAttributes,AttributesInterface -526,Bend,ElementInterface -527,ArrowGroup,ElementInterface -528,ArrowAttributes,AttributesInterface -529,Arrow,ElementInterface -530,GroupNameDisplayAttributes,AttributesInterface -531,GroupNameDisplay,ElementInterface -532,GroupAbbreviationDisplayAttributes,AttributesInterface -533,GroupAbbreviationDisplay,ElementInterface -534,Identification,ElementInterface -535,PartAbbreviationDisplayAttributes,AttributesInterface -536,PartAbbreviationDisplay,ElementInterface -537,SoloOrEnsemble,ElementInterface -538,ScoreInstrumentAttributes,AttributesInterface -539,ScoreInstrument,ElementInterface -540,HarmonyChordGroup,ElementInterface -541,HarmonyAttributes,AttributesInterface -542,Harmony,ElementInterface -543,CreditWordsGroup,ElementInterface -544,CreditChoice,ElementInterface -545,CreditAttributes,AttributesInterface -546,Credit,ElementInterface -547,HarmonicTypeChoice,ElementInterface -548,HarmonicInfoChoice,ElementInterface -549,HarmonicAttributes,AttributesInterface -550,Harmonic,ElementInterface -551,PrintAttributes,AttributesInterface -552,Print,ElementInterface -553,PartGroupAttributes,AttributesInterface -554,PartGroup,ElementInterface -555,TechnicalChoice,ElementInterface -556,Technical,ElementInterface -557,EditorialVoiceDirectionGroup,ElementInterface -558,DirectionAttributes,AttributesInterface -559,Direction,ElementInterface -560,Properties,ElementInterface -561,ScorePartAttributes,AttributesInterface -562,MidiDeviceInstrumentGroup,ElementInterface -563,ScorePart,ElementInterface -564,NotationsChoice,ElementInterface -565,NotationsAttributes,AttributesInterface -566,Notations,ElementInterface -567,FullNoteTypeChoice,ElementInterface -568,FullNoteGroup,ElementInterface -569,GraceNoteGroup,ElementInterface -570,CueNoteGroup,ElementInterface -571,NormalNoteGroup,ElementInterface -572,NoteChoice,ElementInterface -573,NoteAttributes,AttributesInterface -574,Note,ElementInterface -575,PartGroupOrScorePart,ElementInterface -576,PartList,ElementInterface -577,MusicDataChoice,ElementInterface -578,MusicDataGroup,ElementInterface -579,MeasureAttributes,AttributesInterface -580,PartwiseMeasure,ElementInterface -581,PartAttributes,AttributesInterface -582,PartwisePart,ElementInterface -583,ScoreHeaderGroup,ElementInterface -584,ScorePartwiseAttributes,AttributesInterface -585,ScorePartwise,ElementInterface -586,TimewisePart,ElementInterface -587,TimewiseMeasure,ElementInterface -588,ScoreTimewiseAttributes,AttributesInterface -589,ScoreTimewise,ElementInterface diff --git a/docs/DevNotes/FourLayers.musx b/docs/DevNotes/FourLayers.musx deleted file mode 100644 index e2ec2fb7c64598e05fcec3335eee72b255a5e070..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 86117 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

K-J=}dHab%ecO^KI@m{r^wS8dL4 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 W;cF4Z;7UIhREdAzot5#U~rB{;thUQa+r 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

d{)M#d3_fX)0{JF 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 diff --git a/docs/DevNotes/FourLayers.xml b/docs/DevNotes/FourLayers.xml deleted file mode 100644 index 11fa7e66f..000000000 --- a/docs/DevNotes/FourLayers.xml +++ /dev/null @@ -1,150 +0,0 @@ - - - - - - Finale for Mac - 2016-09-12 - - - - - - - - - - 7.2319 - 40 - - - 1545 - 1194 - - 70 - 70 - 88 - 88 - - - - - 0 - 0 - - 121 - 70 - - - 0.7487 - 5 - 0.7487 - 0.7487 - 5 - 0.7487 - 0.7487 - 0.7487 - 0.7487 - 0.7487 - 60 - 60 - 120 - 8 - - - - - - Score - - - - MusicXML Part - - SmartMusic SoftSynth 1 - - - 1 - 15489 - 1 - 80 - 0 - - - - - - - - - - 70 - 0 - - 211 - - system - - - 2 - - 0 - major - - - - G - 2 - - - - - - F - 5 - - 2 - 1 - quarter - down - - - - B - 4 - - 2 - 2 - quarter - down - - - - F - 4 - - 2 - 3 - quarter - up - - - - C - 5 - - 2 - 4 - quarter - down - - - light-heavy - - - - - diff --git a/docs/DevNotes/FourLayersWithBackup.png b/docs/DevNotes/FourLayersWithBackup.png deleted file mode 100644 index 8febec2cfbb4cc3399225beb4404e9f07322c4fb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 207463 zcmZ_0WmsHGvj#d046X_85`shU;1*niI|PCScZb1U65QQAxH}}l-Q8`l!R@m5{?0l3 zoO|!okLjsZRb5rRrmOm0&$Ggm6eQ7*36TK+0GhPaCuINt=n4S9fDqwdIex#oIbXkE z9F-+S0hOb~2e0E93sp@gO?f$9V_R$HFJEnqOqkuQ?Ovq-0Dd>#*P*qE(-(3#YbzT^ zUN-^Cza@BI$A7U|D9Qg8ak3Pk)Rb2u7qfLRA?IY~VE#ZUh)hmS&hPNmlvnwa#DCOZ ze+f{UJ2~0$vaqubhmN(;>Kj-NcE4A|FZMR z#L?Kn!p_OU)`t8qyI+iKot*?IDgT=2zd!%@>11L0KQq}l{wJ*009pRJ!ote@f#tt# zzpC>8#pM;VwYGCGaddpOFUZONx8(og{m(rA$SaxKI@!Kv!NI~<+Q!Mm;Z@n`%U|9J zvi(Q<|6k(&+ER3|FnNvoZ*A89X#bn{A9;S3zXJbPBL2zp-`v+U3nKHg{P&UxB3Ey* ztpEVR0O?O6s%|jH?RT{%GYNZ*V|GP14*taWKeWJsm~pXzGTCpK67n5FRyrT%4nw0M zh#^mLRKzY&7Co%z6>C=~$<~U_u9ax>keQj%StY_)OmaU=Aj}(b(_ilfZ&pdh&i86Z z+j+j1ysK3%Wt=C{?{GckF~hK|YM*tjs=wy#|H@`TS7Lp;(W%P@`rq{YtduSFsBxi! zeQ?sarqI8;YbxR7>$}Tx!=Xa{FIrE>rX6CN*=tK>`HK7%S(gp@G0peMc1%m7%Am*> z8uOf1=X$#8xElBO<-bI}B70#XbI8YauOLvUcF?G-D=V$fN6qCgM6QSACfy$$S#U|0 z5HwnhEp;lqoC`g760GYXQ||Hpmw%%ekisboUY|#|N6aj|cSNZ07E2A*=ToOQETNG} zp5AyI$zG0yT_7bxFDHhAp9+CZh0^R4f=02pL)oDrWIi8Z+fcH1`d1f+O-qiin6J+t zbqj@GscQ`d`BA^|cy?Bu*X_(Ob!@Ms@~F=H;Tk_aD~41cHFQq4)%8>%Z(<)7?b@O0 z6c&wgEuPNqJ9e_o$fOagtXhAtd8%@!&EykVCw2SvXw}pS*^Aq>hY!jsC5ijil@lh4 zq5OJzfi+&q$%)jQUhBhSYrWfMzzaLynYM><1J#P#NHoUtIN8Q%?t)C!)Ah)7DrFz^cs5jG=@O=27ShV6Q5Kr3l{Ir$Qd9wtq$ZAW4 zywtK3mfi0>NU-vqnR=Ye$KM_8qbn;~wqEB8@CBc?-iUUXo1GSr`5w_&?BR9%fV3Ie zQN-+evj2S-jLP^q`tvba0r`d&7quU+RV&0TGla@KuTPfnvbHvPp0!qvc7|#?9G&=l zGwAGo(<(s^RW;PKi27XZ(D60|KC#&m#&v3T2=*kS-#9_0Rk3l zZ;D4SI#M$|p8KbXVkT#@THf={Mq?Cab)MCCOAW61unIizwclvP&BB0?l={?#j{QY;}NmpZvUW*eI+|O zS~~^1A_jGo3}Hs)0!F`#sQZPj1|WZh>#FBYg2waevo7T7X?1ijA_bTP2EJ@}K35r? zpn5*lz5L1eyj43UnDqScveC&`aqWB8`9xOaEqE!$Cws7n(2)*Vd1|c1&(Jzu5X1xF zmbWC84k6AjjO8}6dt2!wWO_UpY6Bqj9efv~t*n6udBz3JpD?^L}S zTex3Fv46eNZEJqlDaf_Oh{?>qRV@VMwt6Yjy|Sab_D$~2wXlmU9N2igblFi#_VinE zYEaN+$en5J)H60+!i>S1PulkRq6E5KhOp_-+QGf@vf$Y(-+Z+=b->qIGL_|h5RD$n z$Ti8*`6NXz_)ydYdjvgH^o`Xg*j)6!tcR}VO5Hp!%uSxwO4bvd78*Q1mOu|bdkx1= z%rq8^t+-kelK4K{||m7rnPKRrxQ~c@u49_y}%vsz{>l z!_Suv*0)FN1Q{oDxYy)QqSL0BFN6-By`VZm@~s_bN`wM8<{rDTtbH*>wjDnvM=*S- zS8x>-r;a+k_yx{ABs)pCR}%!Eejh2+XosJ*OkTU@6WPos>U&#=9KTcN-rm?fV#y!O z^q{crV=`%ZhKv=pRxaUWr84bb?Y}*!-)V9^?xb3Ay^$}uj9_HgnS1H5-dQ7T$LGL7|-kvZWka>C8P9{7)6>(3}*qBenjdkEAl%KqOx?f)5 z&YIk-v>AMvIu%U2_VH5mfTXPTB|QjUHABO?Jr5of+wij<=9UvX>~1P7DpHHqp3ZD1 ziROIYdp{3UzSQ=1%KJY3S~_^H5{RuV9dbIZHz*qPJx}}ejxO6ZUhw*0tYAq}a`NVR z_jlbE1YzoFuGw!vrt|*#X7Wg5C9dPX#4<1HQSq-`lPnWRLp?)a?d~S}p~0cw<4!Ji z&+Jr-r0!#0_>`bNdTzZXg{g=t zQteei*{b$4nQu3GX)Xm@2VtiIiL1p`(pk@O2ve}GE9vNhuNj_@4Qak%^xhwt8UnO( zhd&*lVEFQQpJ%2`wXz5#WD0$h?iJ9u9L{kHRL$7gw)04tqH7d9Td0d^SQF&fT~zlt zTG3i`-|8p;Rm$sttT~)pt|4QEd^hL^Z^7|C%S|1;__O)k7#NdJ7y|Kvu7l18`wWUj zW)@`(N% z$dv~_1y9}&ACD^7UE z&roZPB3GX~74S;h0R(|mF01o0n8W)r2>Q5T)ArVF=S&@8xkAj+6xhIgs}{K?9|Jg^ zh1@#bUubm1Lrm8$(y|0ISBdoFAg%5i9uIiKto*Lq3t2@;G?oXDrHrz_Taaf>?2kn| zkeC_2Wre~n$rRwtiYrD)Tr~Act?Tl67{;e?V8rxN%!~YenF@s2_D=5pe((@F#NDvj z)s->lf&dTk-hX!5Uy3Pk{fKBMX0@XL*;|bBm5@j2`ds^x2@P7h$tuqcJt6?@Kdc+d)w6;XzjSX;d07j=xsT9t>kSC$#)xpKTI$av>x9 zRpykKtmuf4$yy`d^7>ew@A|suqM^wFkyh>?dc|yUK>4uZR7%5cKUaotDwBa1j|Vey zQt?K}O+&MAGMaD7y3qLzRMb%v+XgAn=^(^Ip3$nG>g5HEP0I8 z#T|ZKktQ`AvlqQWPqGdnJtq9MW-5W#?#l4aaIwwo<)PeF&{qI(>w#`lw`41G#L||~ z;JxeTl)>z??{rjKRhWc$FnzBGQ6;HfKb^BxLW~ z@^o@qNb@q(*c9hZ6S!`LpgLO4?fX}0YI4HX3@f;qF>iTm42dk$(K>bN&D4J6r>Y0v zWLCY_+l;E0JCDCBl<$23OCgQ#^EN_d2k7{?^#wk^Z~jQo5re@IqoxXm;=VVKU*FM+zWH8wIZhYbJBOm*~yn2 z{pDQOfO7Bv1`Fz;Ed;8&TW%iGie=$WiY*iXso~xmE5_67xi1MEkX^8+*%b7$ys!ye z4-HOUuNcU3SK%GFva}Jq;-2!SW%4;$-+xj#ckp+(i;?paf(P+h*e52!84paQ^n4=U zYyI=+eYmE7NqQ<^(EPeg1}~Raa(=SXelKUIFIjcGI7jaf16sZ+UT-iWH!mhuZW;FR zDGH|gJgj~;szEQn<7uh})wP;>3ZY#aiKTWX`aBJEa}bcpvIt#q%#CW$Z)G-C$RM3bBC>-iI$!d+)3)&Caa-0x4!BQ>6pEv5X_?{d zAe`CEJoMf|!G&pS7ru2;eu?j+$JLBps~J&&(oe6a0_f}nbF`K7*aAhN2A?+ZM~8PL zL8J&6ZQnER!>WH~Rr+`6Q54#8DXM^%Y<=y2bj)1aEDODyPaSj(ypxY<%j|e+Co3fD z94A?hO`X{fciJ-R1edv|XFj5zTYe`5EezFb7c_~6IFHnXgFTor=L8-2O8$6f9zmer3x=*xQpIxaV)x7e()if$uZivYJ(4&-0seIB+@EMEey z+1HZ(I<43sr%yQ)^^d~!@3ye7gprSuMO11sx%gcFpQRS}n=|kgXusA*FueveT^oD1 z#9jz8EQW=YIX&%lCJ)32{>XgzjWOkT{^ZeeNuj{~CPwYJMbO)8jObtv+&R}YyX33V z;$rt^HA8OHGgp+$vBBk|z||I6#^ak0j$>H@>5zv$XJW)#_j@khP7;W0BZR1MEyF?M zwDgJC#*MDMJcpVo0Bar>g|dpbDj{m}Zc*;M#qSLA!9K`Zl#zIFq?)}m{#+Chrhs;tJzw5j_~ zM0uIb9>%4rR=OwvrO=jYafyi_jseEhy6T$6^1@SXZvU8%(+^xG!>h^=i1Zw$qy{F6 z+k+*-RBeox(8AP22ZLY0mU-3wiGuI_c>BSikQ>_*)V8IWOxGT^D8jZY*@Ko`B}%7- zc6Q3!;8|`FZu#kUB57*wWqa3YjmEa?>8T9*G-v;Hu60UYv%7`x7_U0^)aHOpF2?7@ zq*H1Jk~Srl^&_*ZgO%9`eRMd{@ND|r@+~pk?$JIL#@W~(`PQ2T#X>z>0Rrgx;_A^n zaog&-taJa>L1o#hoTAWO-a2)af#=}fr1Oa%lzXi0yNko5>q~ahBHyXBM#pm;^meMM zuxf2c)A9FTC%rtSY(Ue~DpSTRk4naEEiX=*fzY*NO4{uuEERF)WrhQnXaVg zwG)CYt~Xkc=WRdgbD#JFRD01quo9&@ zcZJ= zT0iv%?$s?<@aFZ8!1eFRDz~+~cy+Se+>g$^cnSQC9Enyq<1Lz6ykB+1hUqErmxO5; zogAImBa;>K`VQBV&wtmqI%@B+Ykj@-$n`R#Lfy5ieC46GN49%&n%B;xK63y#34n_7 z-cXueKwD9iH{Wf-7isR!7T+*7rayOqeBUr;ra|@&=Rn+XWPcr^oAR+gvNW~kSM2;@ z0}1wEYxd83V@rK#Iox$(DdBS2aOp_b*SY?Z=k46j6vh!?VYeAO7-Ajh&YuEI0pf}I zUACC86izybeS-JI; z@k50?XDaAIT>jgqzd^AD+E|sG^eFnf*8gKZ7KngOEVcH0-8d!7(vIEUx|66gsnKzf z;AT8u+DfooLHpg;>~Fa5AJFd=8yvuPdu`{ZxI50HwwHR3gO~hQnr~y3$y-f? z^53R~B>W8${RI@o(w$A@3&XpTjku5H{e!RkBmb9lKr6;U-|iQae}(VGK^NP-BI&q# zS^N*k_79vXn2-Hy9U{hCH>dHN5eCZuL!iPI|fXZ5x*y^Yk4e=_hcl=+Jo*+`0&hi5_vSbkFMdPOnX zeKw)dsMER1{V1EJ=c^98Im!;<`Mh=@Anjwzqmxmz>XG}*KKKTM?~U6|B$pz;A`xq_ zqwb5hH=oI;)2*$yS6TNV){IL!-rm}s$i*Z03f5Dd3^q3A8`JjX9gU<_8H_Zh{#6Rk zC;Sb|xV^gd_7WK+wwg&y&4ub-b{Bjdf)lCEF4nIPJx&&W5%BMb?a>eML=WvH2h<84 zI_@=h>dv-j`)6O?Eo#paKpQ_F3Z36vTz-32$Y^ZZi|lY3V>;O5Jk%cvR+FB%y}{Pb zuqtcyIP@AkIhP`^oD$ODr|`Wk@As+bFpz<%V%}qieB8N<%hF&sC94>7IBY7fjYDdv zO+9Uj@Kw;~s~;;8Jk9V8b@-;JepU6FV0~}j-P3Zh>|a0j)+C8KFrs+_sbKhb&Scr_~)vKK(lj?#>-XmJl?FLy8T&;6aZ1{OX&iZNL>DJ-~yhF}<3 z?;nTXJhd4MU$NDE_fi$Vy8W9!981e`*1lcbjP)&ViKrDv@G?G@e2d4^F3RYY>t~Ew zV!JvLw3ge*_>wvno&U2iYT;eN)0foIC63|{3pRmtkM_@mwl)RdKFB?Zr><}jFiGX?p_dZ=Xi7Fj4=8=;Et;2%`Bn=h&=6j|hM z7GOKxbK(~maqZ2KQy(f3a!KQedM>Y39l&i_mh#G*rdg<7Z=K>UN|zZSbKXZ33#lz> z5?iNo532AK`u6_lV0}&$&%fD<8p1;vdbSl^CQNJj;Hs*bc4Pzd7)Y^YGry zwXe)}Y7L5oXm*=<(Vwg4W~uD|*f-9yccfZVNfrxorA5TGAL_}FGqv!xrg3bLUW1Qx z0y2f@>ev~i6b_4bHnOYD#G3Ju);yI43XVH>te-9bl|>Fs5ub;<+|5 z#21&-3$FyBC+xo@QYUrpwKXtPo~?#y#%nkE1{RjknPNm_A+|e7*4@5>D#E?Np2uQS zqMZvLM;`c;+YOH=2DAMe;h9n;Is)LK6j!dI{uLY{FO$c#YcnNu4a%MPU0K$IlNd$q z;63Ft4Hg{OIk>fM*$C6PKYP%eO}osa~3MMSE|es8@C|rv4aAJ3i+A{o*XhGKH6L zTSTNi0=K!Nc%6E7Ao4ESBc5r9i$b&-&P$DH&W2v^A>(xu+NmoS`-y%>dlY-K>L{S= zcEE8TB;-0vgG+lBc&3)D{ijfYI=ou^S6TkzE@n^bn9(U!W)u9lXl@~VzhB}>ANCEM z915ITC=7rkR}ienZkR)*^PqdwhaYv@|5Fvv-0y_a9}X5hi&WZ26E*errdjV=gcGA> z&TQlW_XYl}EVllP;s9WWih)(=hE$WG^}6IuO1Q8CxuQCVh`T0>=`mO~`eK@B2*slc z=JjGYhGfDyz}gou1Bj-FG`aUQoEP&J*?VA(tUM16&H+(8-fKw=21(SSGpGH08*?2Q zR3fS?Y0nrf`LajL0yC0sMwsvi4luJ8bS!zM0j!`}9=zQZOAQ{#a~8BNAPtu?{Gn~` zpKX&;8-B0$0|btQkG=B`Wo<(5I;#G(8A-RmRj1Td)|H|O32^~mEX+!jN=~|G--nsO z5#w}OzcZ{Q1^1yYUdik$gv4p*T{S-@4kb_=2xUg@Yzz6r|F=42SU76vL=pmpGvko!=NCgO8_#!15#f!%FE) z&|{WmI{<%9s!Y29Y-j-uzsR1uIguA^{2vMq%@lx~rCXF^^kue##5Oy{LaM>s>tT^`uu$*nkt}1y(m& zUT9@Kq#%ey$>4T18d`-lSM3YK9ENAsh`fO-P3Fr+HsDq{L@Mtrm;c&*Feq@B4($zh~-QBIWJ0_S$2XQV>SNtm1)C`71YvY0Px}GuV&Y%tKDF6%z^y_3`^j`xbfo^cyAuF&WcT!?~?9O%jzc=3K!-m>Uv5G z$c36nW>4sR1=wLj?-uMl4d{{K&L5>{+d`H;lB!>TXRDFliVCo3@&Or)u73wz)kLND zQ2jzN2}z?|njK|L`Psdtz}>41#_6HyN;kGI7l8r1vmCA8(~V5l?=~NKKN3b3Kl(Q4 zp`Aq}OS>9B`)3|n>qecxEcZ>fB>kLC#d#V}eO1^RbsA;z@FMLvLQCKK2%nj9R_2QU z{$uM2SFR1GV&(UgEJNq->W`L6khImU-p`+XC3%Ay{}cT;?=}a?=0!`_8;4zB7SF?p zjDC0`&#^Iuk&KHkny~x^no;l1ZUI_$7>$5fb#lC!(4ZA9Y*mlcV;y06A{|~6z8=`- zg8Jwoi>^ytoJveve>*b68qseTVoREky1?Ous~e?6_Q3oz8QCBH)ym*9a-%&A@^wN7 zd=i>MYMx|-|@P6xC$pweH7QP!(g9rlw~u#1(b$$KU9y4CDy z>z}8WP_xR|L|$6di236DD0K>jrC(~#3j-to9&AHUJ1$U0SdG(8*Pnoig4QJdP2hSf z4tO9_B+a`^yu?}dC|Ur>Sj@-ZM^=|HhMqHgG)<&9h5N@+YOT9}GMBRCdx^6l;>Klzy&Vc&EhDFKWh69<2 z6q`wNvS`T-z|k;o4oH__Y8=mB;LRjt^ov6x|2-CIff8{D=r@?E1kX+yS$r!LC+yW> z3U6Y;+;bJ>ab_0Wdke^8!;NzAMnA0s8gxrczdd1XriT7t8Jfu4X4EN+Lvy#ct90^GoI znhLZ2WHc?ZmL47N^7Jp=@mU*l@UgVT5YTP6vUn?+dg+gvu|5BHZmEK3Z~>8S!8=u^ zOxJpOOO@L#ARkPnR+uirM*Z4u04=VKE?hs`J8;*t#W~J&zZ@?uxG>aceroZLseg_< zpvZeS9a3;-_NWMZ&r^uS<-=Gap5qZHIFLW^O zyNryV9H}{KGn}G8p_!G?;MJd*`rP}1vxUX+?Mj`wMFIKngiaFg5Bx6npM*LU-lEUz z%!_zl-%MQiERYNl5UpU0S0s`$%`1Y{YogG}XCoSpi__IV3;-9KkTPM@aXf8qzwOH3 z=}dLf5&agdSZ`eCeiDD4`!x&?g$xupWOVI=)Z6{mQ#rYI7VvL)U)bWY*rW)kgtUL6 ze@E5|`AYJ0nxecSg06ByRvC(>(NwqW4N?**++QrNC;w8z0P}7Kt_$`T3e2GM&Y3O@ zNJ+_e7)A^PFoSO@wb#K_8E;Kwhci|je*+9Hs&8T(l43~rhifzp2r2^P=YI(>RIxEc zvarWe)<6OyVFq6fh>U&aK*kNqoQ+ByLs>TcLh|+ldGpb0JTDim3hq$o!uwZQAVqzJ9{S;z( z1_ProfY&RmD{iZyW$la{`GV z0X7V+@oq%Ou)lE91X?m>%s&X1sA&?JorMr3SAgtg#liF78&d~6LY#!-p*zTH?P6gsT4VL zWJ^?-;FEp+bp{8mTP0*jAkW#0j__4mz=RXtDuhiVAUDK<=()W?;l;TK=nrkSN3Hp7 zZicS{^FaIf4LIYjp3TUq4U?+w?AFt4RgY_=M>1+pf#KqauocMA0J8T23eFIYdLWW- zTJ;tIo8XV!G<879RI{Y6we8uG0oCuX)+J3s$S0!Iq{)gd-i_&OH_NC{O$U@5;HF^& z8-EPFD7BNnsS?&FF=F)p$Xh^-+?=2}=Ex=R7VN5dQZe4cOZ4Rg?WbYR()>rj@9#+E zuv9AZ!7^}%M{c#Sf@kbU3LayogYQtB>I`I%xtIq_jF-?$^C6gAm6nwefdmimbwm_# zrqKQ<+z4{>zvOnBi?!yJ9yjjL^%0ESTe;WWj!2B1Ll_?Jg>72jp@Xh>bB!Xqe zJDgB?;i_mH_ybe5W>sQ&bacRL^bJ1L%uW@1ud zb+A?eWLK*gfD|Mhai%_wABU4vPf4y$aq{dKCk5EEW zzS85sL{#;tbB(l<0^k>9W~Hg8(#mef$S+LuJ>2_b6j?08uW(I>JBwH5=z2Z%@_dl+ zZugQ!;cE1{#dEC>ejjjYQ4II`?$rc^wJ-zBBD2s3;QK$1>j#M&GaIT-Y`(`LZ|XJu z$`4b$eJUZF48#|Y{?3Y4vNrL}qQp7uycGj~n};7hYnQ}D%ZMg~q(PjqiSahKy(dN=D% z?fITh15`NVEkRkHfc0w89xs?5^KMXkCay`i=gRfQ&)|J@+PYz$W#f4QaSuzao|FFf zaP>rO%3l_8LHBTLU-W9MWqEqg22L}{BU>mCjg3e!jl;cBt3mt0d)p==^QvW}ZEU$1 zCYoskc-B#2oJ3fb>NV)O<9kS6Ch6a3y*neDO)BdPyJ5|DH5+XR~%<$Pfkh)U>;KZ|)B+ zKSoesyHioDU|6juhGWr$VWNZsBIigC{AbV_Rm$9+B~O&tr{!v<-BwzaQzGIc3R5)R@B5H8U4a5fYEV;zm)= zT;R6#2%qHHIV0OT5z&LPtW{V#3Ehmn?bvj?Gvhfgcy&AZ$MD$Q1U9#H-)f$$B=1va z$1M+{`D=eQLbHa;jxLL7RU-r$52TBFny{Z2U6%${c~BtC18O$dXPqpv^IrIovl+gl zP_KrS8a~&eAM7$7#g>aD^7bXTuoj51;9YJLjAg^uXaX?jpT1}c^D;y(&x|U8Te#s& z0C3nMiYoB_l8vZk1TbNmb8jXs__yKw`3@Di4ksHB7KQ24amA!v-0M#7_}LJu>{6>Klx=CMUk{DO{5nzNF}H*Rl~;6|+D&FXO(C=^4l)Mz zbQT2c?|*5&9|9jbrA>#LRS-o0NJ%r5Og<}J)6a?fUHMavPjKeW{GlYjiRl*qo5h1F|>B$u6~ZC&0&MesQM7guX4uf(0bkgn0Xi@hk@|%hq6Q_^{rR zQX746M^T!?QLk{s+hV2l4m2s7ITX{K2OiD&yYI6OaDho`13@+BcbR(?dJ#jwe%2L! zOvk2CKY(mMzxsGyjPm3?#moM6X^r}Pl0+F$rWOxb1+;QC-U}E_z!h5QG8U3>wC{irvWcaYAj!)bj{CEqoLdY^_P+&4!1(j6PMWMCzX56H;ygfz zVTrY8lh-UP=m6Uw@61;FO(Jd)*zQl7K5h!!C9MKExsb|R3CV@}->}5UY0=cL%g!~js)5@efXJtO44XguSzbyo*pZww z{qtO4*8BN>3+t}am8XEZw~GM6>S7%Jsvwm)F0_GU5JEy)Z_TWsu#n9f64A#|0;~uN zD~j3p)fgJqol#P2h_4o5_YvQ2MAHJ$R(@(%3V@A5gE0S8 z1Gzz*Y-L@_+{i;!j;L$}`W34u@7wC($Jh%qNzwj@x@V_@2d;(6PserL>B49>7olhSL%SxWD+HzR|+Jx%lde z*&D@_1G`+5P!nWZzpoA>@m-PCY@7~#^OxgwuRQJJ+qOTh*wI{f(?7KPP+C@t$M7wT zQK{1XMm~*)x1yMzXnz^(!*B!$TYbkuqd;)nVY?Ump7~d4)Cx&272_4aihuy0KM(2U z0>!?iIGl$lz~Wxj*I}&%##Y$B#pH^(5Dl$$%&e}RI%Ko{Xoz)0jNg4@><2EIuYNz% z6oQIR7Ve=cLz~TmTNTARmOCvIO{K7Ka#fwnfry%rN~7z{T@t=bAn_Os#0~lxv_8|$ zC(eVLNjo!LG`@?ZxK!DrJ}|vDHz0a4D5e6* zms866%)ovWhJ_UG%>#kcMtHbl@0PqGq=dWdusLRV6VVlg34f7RDkoqv?Uz>6z}es+ zfW43UXeo~yPqtEJ0K!H7yN&N_3Do&S41je(ENHRX+0zo=I2Fa&whz*Kk&cH!+}Z}a zv_K3c>~SZwt{FgPFr+xo_<4(~9oCIB$U=#6z%R$*PQL(b<6Y+l%{nzEdfwt@K**($90q!KOO!@3^=lYdUBxn*G#B3|nY$EdgB{4eY^)P==ka;jxsc)3AKlx*hPWR%Ov4RQGNt|&cV$cWK43aFLa#RN<`N!DiG75t3Mv+#%9v_Er=gsKVj9H zPu!FCcc7>P-d*;4)(qehZ;xNOgOYzNz-)$D7sh!}1bM)6QYKLdAP` zq@R>=oy{0?Ros{e zz0T1cwZYGwTI7Xpe@Fmml{(pIn;=|-$ct+}YO#1R!R>h+QA(_3cFb0iX+05o&iv8E)AdP`&%4{R*y-s zYgf86MD-rVz{9|D`F*X@k?AZIR@vYl0V97OZfK`P)>SsnqR(LJW>v%SSEW#+${8r< zUlsB7K}m_2E;F8rdds>|roaF0JpQv! zZT~!`#vObx*w_Gh&PF1Jvw>*Hk}qPQC3;G%}|d&eB`{iz*pwAbs49H~E? zunmAPT>2Yk5Qt_0y68VJCK?+xz*8BO-7a6d*rNcjl&Vu7l({+55SV^ZXY=W1Kn0A% z>ox5wV$!sY!(22y-;=+MH`hB6*^)BoxdmZqhwxeI$9y3{b>%(oPqwoTXG|1-E_QnA zzRA&bep`l}G6)c*)$DGDs05tWe?@L9ooLwMF9sh(c!Pd{Fw=m;DHo#SNNUTd*tAcq zAs=Sf8%^biAjxp_4KY7KFZMJ<=v*JKJIR@(#I5v?`))^JL6sOd*T|Gyv?m`YhV)Fa zEKtftpi`WL2a?2+{6}WxKfG|gc=t$cX=~aN&YE$5Bj;iddx~47k{2-qN{=T+>$l{< zbOxK-eJ(5M-x)X4JG{THNqk%Au!gGPRN@M@i%9(_FJJiwL6MPx8ypsBFiw`0H*F)F z+)7}mFw|NT>GZuN-G0$wtGC?|U?8tM?_t0|gvLfwiIFb~mN;?{+aa83S*;#L*;eSj z&*}+*_2aSxY!h`2!g7SE98v5!8Q1clS{6D|9rpcf5PsHNHm~~yKNWIo*9~v3hk~ac zf><){F$lMx>pW$FwOp@>sdK-=VHJuG;bkizhf*r90|Z-RQMaQLHDNe~(tf?7Fy#K` zcT`-O!@gD>03(=n^WOQn64p#BCHP^n-bYQY1gf)Y1yuYH)|%Z60vgnm8W7V1P~>C7 z9(?q9=ubQ=wq*k?Iq`%y>hj!87Y?%&;}KWP2BsuGoTbWtM7)?a4>Nc8zg48Plj|S1 zUJOK_XBWzqfiw69+U)zLAVq;YZdq37Y~O|_+7#YIj?afp$BYMe4S-RVFyy=<*rxz~ zl4y2xCfi365eYeL>CR}h5pJdv1gPTbrNMOd2>AQ=g=gogoVkbF6guSYPkzJNuc=L+ zK`c@TQ>E1@l}vU)K$koC83tw({C(}bgv3@z1Vur~1C;h3`*|}RM)?BglerHu$!a*( zN2kCS z(_JOIiAXgKIHz1#h2i97*eUtlila#2g*y#?V_eIPL$SdoLg4PYHoXj!#>O2h;w`&VWV>P~E2>t_^e7$?dOS&dueG9Usuy|YNf z8?at5pThXW$lAr{L)L+@4uY|!a-t5$M1CbICNwSDjR(S580RLS)K|fJ;xFORrMRF2 z(fMS#kK!wsW*W8X!!xuWJ`3U(HP^c*$BUC<8oBrSqMaLj>82o62b7lC`0b43|NMSq z4QR55&8ZJ{M~k3w#cfFir-qrON{q=lnG2wl1I4-F>2hpoMe?m@}CbMin`FHrMIHr+K_rO z%v#k35zoV$2ki=&Bockp?eZXOaR+4g7tU3hFR2zzu{jR~ROFZXA$W())AEslBtu7c%>~IbGAFGQ-cX4A~D>Gc>fjg2-G7 zaR)}?CV5>2IA-`9lr|m?2obBlyNb^)frDb0hBUMhm zc*188@r2T*2q}qbS1L_!<07KN$tqP~TNvXNwMq9h#AQ__Z`3;y@cKawmA#+*{##nTJU&2g| zYBNl;8+_H|J9j_MMgxDBG_d|f`g{6&Qrvlh$8s~L_sO5#Q8Yt7b}P{*AQ00QP9-B} z@5hATQF49r3RLARHUy4SIfuE!q=@t6ZrFAY58MKTNl3HX?JE2oWCrkqv33j19`R-J zi`Z~Ea+(CNCz~nm?ME_X-77bT(&@%Fi zkRHq_;46Vj*%hij%5W(t(94eh*A1Zj;1<&DCHP;(NXUg{xe5(AT@|zr1 z@>XgQ)b*HkJg5*(o%vb+$AG57Mu2-J7<3N;qerj^oBA`9V_bx4>08UJk5Sa8fjVkst=l>H5%jio`Ip(CWtX$26NfC}ugpxKjp?P{ zP5Pp5DL3(Epe{^P959PtMnrK{KVig}96RwHN&g@1?G)a{4bsJ4)5RIG^FYnVDEExGw2UR~!LLdcr6 z+b)Kxw2TUKmQ$e0bgO@qcr>fIfNh9fMp4tc_yI+f1^40&xnvWYc9HEUQQESCdXMp$ z?HLxd9&g1D>nrZ#!l2jj20r45a-rZ30@eA#9XuN@3W?bO7X0EKT*0cWBd2aq!C3y0 z2=mvi8l!-bs*s|1-?Q&&c;PiI^-db-8S6sk(dE$rYQu5v= z(*sICmU;|LX-TPVv83DhNS}5{DuQiFZ%<0JxZ|1FEWa*Y>&)?7nY`A>&<#wjkm`4o zXNe~ESkzyCi}T-fNMbjR47Bc>i3C>C8qGUVtTWTjo4C4n&JT^MN~EuT(zLcPL7Wow zC-xhYgrniJfJP`88OKFJG*z8k%N5T1)2Nj+B?wA19xUNpECt5>Lw;~jTmWFo`n$I? zD6)|p$bjD%sTj307%GWc)C)#u!oi>>c^FQVcxkf6X(E`PQNscWtM>sy6w;`R!(tN3P|j8I1bM0`~_y@zzhK_$S&Um z-mhoCI$-?7KLbV)lWyQ$cYSt_u-dYGlXx~PPViNjnZN;k`HXf7<~2?y5#vX}KfU~e zH?(kiFop2vRM#ljEY7)Vc;MOa@_W;ZtS?c@?AO_{lG0~#JqbY$$1yIsv&l3SOv(BU zcHSwnQOx5Fz@_HuBwBwdoE!(cj%r=R(i%2IYGfQLxEsP(%`+(G-%Pr^3R)I=v;m}4?=yd5nBYK}Yv8Pcm7GL}Nqcq@!1Y~F0dt)2F ztEUY{cisY$G^`u%HR5Hb3p&FJbeC1)sKm|Jqi0X*Hd*tS!nEtW8BV1cbrRH$-A;t$ z=Q)|Z*Rb)jfHf}wK^%2kzTBlwX{bdovXlQ zsGYy_5C*u!2Zzv!_XsD>Hwym zA4JSV8>ktuyA&VPdIsBJEMSk<`5Ogsegl5@v+NpS1rMou)UO|%pdrUfXXRk+96#HQ z1IG`AYy&*ENTgj+l`{?E1C=*`a{evOouGBc))SE|knohs!0d@%F2&DA$6k-v2zlV+ za`@NpDcXU(7em3nW0U7UIeNF zVcS5qz4{}2WHWZdq}kiJ2Z$&>Ms=%n{shJB$#b%eN5;gSeUQ+=%%oM>D!iwK?ZAC~ z6~sU90$_Sk&q9UMl@b#xLs@a1?xaU1oT$3{Er&wsW)UW7Su+~66x4yEDZklA44(2* z_pb+h&5WE*{W7eEcwkb|GCJMTgNof`&tJxdprqPYq}n7KqK&$r7G5PgjQYd)Y@pF? z5myo;+&^ z>0;e_8(IVTPvy`8YT10#SH3|(>k(1?u3pb%{NEf4qxYMD)QeNnMQB4(Etss-Br2YK z_Ec^M*SHV`08F2(Lxmwk==(Y&lvSKerZSaCEl3OZED8z>p?S{2H_7#;=>oC)&^&-L z`~r>y3~`HKlM?Dl#TuXi>s`=Cr?tIikfy5uxJipp-rmbNCXtqgEASYTKpy}goaD63 zJyFeQeA5V>;J0TW*)0>xwuLEH&{r@og>FEUzLr!+xJBUE5XCwxJ&6e5-2{TK!v_oI zQJ@dNlD@WLS_zB6_JWJ)GFD7bRl#QsN)eMW?rZoYV)Enx`MIk>!&|GR1j@&&nM4M} z0vZtqLSQ}7UjU3HVz5xqJQ1HoY(NG+0t&;5#@8tPEttXcp2k55G<8P~J?LaC7$s=x zdh=8!Z*|e#W=v*_JGH=46JP`rS{%|q!E2q?h1Z>W_jwASz!*#qPdO3Y27(O-E@V%K zALp6vj8}P}OTO*=;Ea(u<+C~0bh*3k`JY0p7$h;FvKIO%Sfb56DR|PNWT3ymK});i zT>$C|Gf{Ie#T;}V2r=oh3Bx(Q1)XtycD;qaSg%{ip&ssfQ-$a$SkW;+J@nG6U|Y0^ zSb{#dWou*reb~g>>j`~d9Tsu}%VNuBWkL?f8s0NjQ-0S4?>cAzL2eRtV0!}Bjg({9 zz?$sL*PblqnsXRyuw^c6GXNl)OssD`EMi^aU+JNIh3t+AIUxA-4J2L47lAjcIo6WY z@}~pmU5X&qYS5UOXB{`3KCaj}NG}f+tzNNa2cmB0ly*!)y=GPccxc2%+qK8mhr=&y z>fB5)2d1X!`evWlu%6h6GME*8jTPl%0XX*UFS^uyV@1{>S%+jDa#Dw|U@oet5iUtl zunSI|uyLC-(QD4v(xK>8kt2Cf0!S-# z2Ev2qRp7wF5N1k46Ktl~iEFJxfDRDG2Kbyz)wC~w?Sj&=pba`uVR{N(QC+$P+M(Zb0R@`US8FNLrM+*PV1)FmdkzCwC>6Ul z=PehL*!^R5f))#u=iFp`okj@S8x-A)QQGYx1U`{C1g3Whf1NjJf`Xxcz6}E{U^f^y zGo>Ojm|9RtDFneO zE&#yo6zh_SqOr1B&nE8JHRuv2OZhHhH`!&V(5JNTTxmF+v}^`~M*JId z1^=03Hk2z#XHA$47cxHpDU_)1CGE4eO5drBYtB4py3NfcIR{V*@_nDO2XwkZU&Oaq zNys{PV*FZQYWm`-;W&M6+73uRG)+p(lKrAUZ-JfQNIugNqe0HJ9)<2r_*5|H3F@%s z#bG2YS;vlWjrxW_LN+s{@l^oD?Z(J4B44Q$03(#XRzyIen*lyAuyV~dd7i(e?+{*z z^ga4!Em%`yy$1Rdu)){5^u!IUnhFc7eAC4;GAQSq(2owB+PWJKto+0P}X6*|a?4saE)!F~%q6W5K$1gJXXL<7K3Y zLB0?Mpqo3a>a^oQsLt(eZw2pIp?PY-Ar=H<@U)eRnVL8W@5$FLyrr|2anXr!SAaZ? z(}q0Xu&G&S<)iH>0CH#=qZ*nhH+8QX7Xi-*Y9ovTI?^2)24JtiwDfZg;6@E_8`jm1 zPpB66u`*i=qCCU+vC?@sXf{TcA%mvMJ7m{VY;=9payVmC4Zs_jG+U4gqqgus)*)Gk zWF2x+hp;#6<8Y<=R`{S}_1L7FgL7 zoTbPR;Gpse>!e#zl@2IFAZPI{8HFd_5WFhW!8$R12>m&`-U+9Hjh)jnt8|YCp zo}K0_1E6Vmjn@-_f;|*4Bc96Brs|zYl@Mx=MlAsB`P}#4LPFZqisGS?mH>7}3w@w3 z|7nFxHE)if4ne57+;rcnQY~Sz)2+`)J?*JtRQWdWns3nXwPF>#qJ^#`uiu)p~sZk~H=G zqor|rX!|)aeccP%&G|?BDtJnqD8ddCk0`BR8+o-uV;F@tHrO3Mz$#R@+nOOA9~q&K!3xZZ}14rsYemmI6INH003j z8k+z%&hcJe<`WN0_dW7P9xB(N2^(zOxbbdUz~HL2tV5XltV6O6VJ)q6NGz<2_(#li zNlF*Th9U##=w6y4D18a~#CSIpWWho=SDP=jH=(I{)%Xy?wE~o=+yx;DRNWQ}GM}SU zLO_J83JZm90!5ithaN)KmunldR}rk<0_bM$xCJb+vqUcnu54ym<|qX%b2Z9|C4^u@ za7Xe?9Hdy5OewK2(3;qfo`Ll|+ha%F#i(?`OTZK-XK7d9G4WI!nxw>^Sh>U3E!@+g z!c~Q#$~$Bxm8mCD)_zcS#x20)XoNKprH2{{;AOW3U@ai783KNYdl^Qy zcMb~_o=jFKdvJxi5!%LqmAKfB1C9o2B>JV{N(CM7xTS6LtC?287n*Agbsi!In3@+0 zR80(<`Tx397g|a<-H5U?Xx&sW(I-Yw@U{dsn^q7NpwrpnrmZ=t>b%KV@fH%5Iqpo; zbkta5rr{pP;(-F#fJe5GI%L8FLulRyOj&$8g{Sz!jmz_;Jj2|oUzldtMxZR~t6WGP zA~iB^B>;vORMeh~_M|ZO5|l5mXyUV0wyk3-WcW^yiZ!Drh(l@nxzuVL zyu=tNu~+~T-TQ+1g1$JH1A!$LPKLvi9az<69PwjVG_dC}D1na_4uA_lzWvvxfrOQ3E zKH7$Bk9l<7waBQHRi;zss?WwjKGo9GZNs1gfI<6O3qP5jXG9-$2}imdtc5-sRz&Jq zSz`op=5n04d0~7y`b*Z6VB9wy7)K;14X{W{zOt=*I|Y}R3&EZ`&C|Vc0yaRhK!`4H zaR7!`&t8B}#v-8|KXSwziYqJE*i8w2QYLuIl!FnT+O_xQT!dTL90J6cH&(0+3ttoS zNI!)_1*c^NKOLL1zT$9%_ef9Xm-}6hy#S`PAsyT}NNZ%)>Xf&qPMKBch!dENq-!*o zmpPomtE<mh#upesT`3f%frt!iBDna;`9sVm|4)Ed?!a1eazT89G|uWLif7&nPrz=~!Y5j)8D(ohTD z>Wvr?b7$Nx&ois6e)*CG2PltF7B@vaZjA9^np(QA+LxA9P7=>;;7s_uY#WQn(Ji0hz70QYb`%BMm{F3`Ow0IU)aB(M^hdy05U zj9?8o?*j~4o--!3Ca0yH(o!X$vuH^QcQ)na>T zdriFI!Sq9H4B;U}34cRnEr_mro;UxcC&>F=bpA)mHUXjXOTM&K?qz-qMd;r5O9+LB z5aPfC17*x{sDKTI{NjO|8Ce7LX?T!k^B4y*hFBn3CkvjdHSfa10>cG>x22w1*Ery7 zvVpta4H)y+9n$HumO4P!k5k_AgUrL)=3hF(csdZ;$t5<<%&Au91`E6CPhzrt1{$=S zF7GW(pCdyjw6;-KmrqfkraWa7T6-zRvo^eSr^J%4?6)Y73#^V>WR>AYMHn`rrCT}0 z1V)VCmiZ^`gNL`^xvWFrp{zsT#H>SBIwTg7= z@X*Rq3oH;uHaJH~DBv2bEWXuZ3g8LhkC2%l%mxa1@540}=~J*o>7q5>WWqlqEIYc& z%+F=JAh-Znx;}lym;3C|Qn6LOw~S|1$}|}5b`}|}Y$&@vz{_i1=Eu|*x)qT@6!O_2 zh}g@+Y=ArdQ<&mJ!}5gdg}4!|GYv|>6N?otVy!@PG>Lia4A}402(N8>teN{g48kBn zX)_kU@QCr4ilVRE3+v9PZw@V7E`S4b?+H{?pG2M^P<@coX#l$!*ML|F4>e#GA!=+3 zc?6B+>s*Yq83z~`moYk8ZL~U4gBF|^5A_ZB5%>hy19W3%Dh-BH$CLjl}?yIIS!9+Y#pZgZL^&=;u z8y*gFY{Bm(Nx|KE*ndGCe{>+4H4*R9vcJZmX^E}?1I(E&bn`MA%21gKhd!$0fw1(H zHmM8LNUbVh6J~Sx1F)wxEduyObnsAEeXwv=1ot}$Qo#BRC(v5j73yTny2GIi1)wg} z(2dHBS+r{lJP1-{p4|NLQIG|g@)dH{Y_;xRI;$o3($BFQEM$i7U=_T_hC+pi)zHHO zz+eghS$AU;EQZpBBG4>}J+selGV6%@lW~dIZu|W3p;l0qeQ8RUFjid%+ zEq$kP$3M)Q;KiJNZdL&;zA2-#`n#bOK+7{q5&D8G&;l2SQ=rJ&b`P1b?(t4oT6ozo z4*ADdmR086r2a_L18FNZ0fif^aPLbOi-1=eyVK`4{fqfRp7mmF(Kc&mv4E%9u$g$cXP4}td%$Iz-lUG^=*o#9GEO@L^3S)uWd=mhNGHZCS3qnR<0Dvs!P%;mf`)~!T zF+PGr-KO9(aS%2~sB|%3%90?xF9{GxSebIRO!ThbZPAluEcbXis1P zA+_ox-q$!)ko$Tn++kW|Dg=4BO6hl_wF}VI#ilV1EvwQPbJiL$eOy5Wb#65+pYi4Z zG;N6`5x-BDI>ip5+(cp?l+`++jm)vb0RTYeTY3YMw1|}`Uv2_aqYjxr=S!$OfPN)$ zI35yMaLU!xCE%S7B%v%KoeMN{qEQvhp(h9#BQa!f8_)ASK(YcD-~gtLuE=wOA5R|o z=8FwLN)LtIUngw|bn{f>n6w$5nl`p+G-9)W0*<#CScSZVqEsEpbCxYrgvf`2RJE0S zMGuX2)Gb{SLpfLRf#{0Cwn*kG_?nAS0L@lrjAH!3zgqAFY`z{?&g^pVdNj8~gn@FiniS&$9eEZKN5K5d@0Pq|2y@SVb&aBlsH^c})!34C|PL z4l7gaApm%~g;`@WWJCcdHU@G455y9}?e1yzK6w_k%$f5}`6lV)t8$F>n+?YlFz!2& z1$i-V0nA8F&UoB95TO>9cID%oHoBzVta1}XSNrTSKe}c0N9cwZ*z$>S&fdUFxHYR$k#d^ zbDwoc$RKAt>yWHN5+1&bDVGe~g-XXVV!(bUbO8_uW8V)NF0ByOtZS6I3)wn!dXSzHr2qw3!C{K$ow^xZK(t(VTh(ls{+~HfgT|V+9a&IAA0ZPWjEpRVZ z2vhr{*ocAxi6CNQsQ^1`?sBUghppmfmTs$x<}pfaN_Pt|sT$9|7{kRAG57c|dVrU0G+N~Uueaaxew zao1oT`=h|;{vOJ_rJrH>(Zyx#8^T#y1|S$8 z1gr_KwaD?kR-u(Jrk_QeexznV`jGir3~(RuV)sy{{3~|U8f7mVU6}M!_iaHixrY-> z+1oc?8RJ}dI*{KLss2q-q0MN^+`otqj(zwHgSMf#2Nym(7LPv0g~Ge z)~Skr>3-9aBR$;0Oc~3N*XPO2u9yCD?HLNd2m@YraeBH`L7#pY?q25-iC8d#qP9JHVToaU^qx=sO|%wJfoSx9A^?!+Dys2Qsf8zbye;1+<3lOb3H&lpeVJcbpMR(Z@q_->3Mxf>k8cH9pF{UKvZCWbcoq=o^QAc>nRkJdhbJ0j&2du2nAc7~ zTmhu&q5Ojd+f(MO4L3)|zJ_a;jm?ZUlzYvL16GEwM7RaKKpU1w=YzFUd13 zh6$lL=1re;OVeNY)%eJ+xOGyNxn|(5*ib@i=0-1x-V-?At9%|t0_Yfj9JuQ0fKpu5 zs@bK6aRVjKC=)!S75NWIt<=3^T6-Ytd`!}D=D6oc^Mq>pKOdQ)4ze9m= z>%6a335kdcZ^p~MXDGN@rLxH`cssxhC0F1kZ2<(PRPma$6iCk=F&Cb@6acJw4L}VNgnq&X#!cL0iIuUT4?Q%lif*A5ide14od`{b zyvoVaz3G6tHTRsf>w zwfw=OB`>94n0^MDEl{9gnZ}yw3EIj@XAKEdVwOB$!#ZVpr_F>;BnN$ z0!$x_O>MM55qIc2fxC?c^DoeYt^%-lm6hPxb<22XSVkSY;BQqTFCJh?>blOSf@D&* z7%Qc#*~3ttdaVJ*-3fK9p#W50DaJ*faZ@Ipz!-u?#zNk|Vl7hL%~8ABs;cnRD7VfqL)|zq_Q`SQuHi@v5>24S`+& zP5DNN<7-EB^P2qGQJXV!(EvQN4hb2Tbx77Bp+j6N7g1u3UBq)|eWaP7Y!Gao{EL@* z^EL+Ed@8p3#O|N#>?UnkD?)=?)a#~5@g+8RjN%!sODg8>lpxQu6D$qfMbYSL@+aPB zi4Zq_%h)c3MaerWyP`ru09vTiov1DK0Cu_++$~4S4i$q~1~;a~el2vXV!aXK86Q(C z~tE}^dA0(A-4SwzYaln<^nPhQ4+0aT|Xc2yl~gzBT@74j-bflIg$ zt#lJ`gtF|T<;-+%Z(B~uc`|hd9h_rbx>|41k64qg;%~th-$NIz5_T{w1p+DBz$n2z zDyyIlik-eQ7Xf6QcK}XZl1q!6dtp)FHB2qmzzLsCyI|?wnHgEf2!JO(5r79$Lp^l| z5$1qcj>k|pZJ;c>6Rk4Ks^|i>#*8M1C(Gqk7W~!aTg;d7jccG!M@F<(KRi|#l`CjLJeT|eZ3PbK>^{g zfNF1PN)$67$2^iAexV5zE-p-B#8kT7Yn^Bx3w2nY;F&mSuGN}ij8nobZBpj}RxyG7 zjPaRD2#t;VR^Y&TWAoq`jAvw^%O4w~ZY(-=bu~y0a0Wf+SX&D$_yw-lSWVEyH`UNF zZf0x%Qb#-EY~(BcU#Rkb^wNelK}<~+MfjnV~p(-Y}MgP)#3#outp4% zU}CxM`T?LoCqcS2iGv=@&y4FPSvD^rD4ZWxj{Gfu0N28@CSS_aM9~2zf%RNB6hjN; z9>Zw^>)SY((S_||UujzLLpfffjT9$Rw zGF5hyA9x(g@dOZFlLNB?yd8%j*Ek4L@HU&^izRUET(zuuHhsqTW*w4s2#YQ2kW+LB z3+AFq=%|Z&^2~=oCBB-<-PeqmHuG^UJWPP#(Ty?RKtLmGd||o&DYiEez(XXBAgg;N zkU~nKgDb$;9l*i@kl?Y#25XneY)8h4DX_G7nXDCegWw?il34E=+`rznTmc44 zbfa3*Vn${3$rGfyMX)R&u3P|{0aV)k`5E|h~g=DKc)9=*6#wM zcQURZ1|B|aHdsY`4cs6OcyNjnOGktbpp0lR;w-21!(3bVbWwPKCHO{5f;_9s7L^1K z2nMK^x;L;OYEdn>0Fsbk&2R#0jpV+|whL2VZ15d%bqh{I_I>{;prZ#ZggCnD+~}yN zJ#=CWQb}?^J+qcR8-*^V2Cg?ik@0$3=cG^%)Vq4`@{CCtFb+?$#`{A77An?Aip#y- zdq6o^4Nw`fi4dQdUrfMZon4MOtdxL(u%OYq22f>ulqY2!e^(5MhhNxSF_H1SbG9J4 zv!%vGx?tY5jM+pl-uD`pxLZDQVDOm$8QuvCHbByot8)PUh=ku>^PqqhQ(4m!r(s@Z z9&|Hy?+unmu@o6k3jb?)lqO+eBW@6O!W9YK+2}+HVWw5f-2%&G!|8HEG$H{y>owB8 zu#S9PS54ZGDg0~76jLenjRjlZOU=*_i}jR)KJl73!bJpT(paEs=tlrIHb=@0%X9*` z?*E;KpoBSuCx3@U!bT4wZCNbfF`Mlt$2**axkMrg0HumVoRA znWC4W#F8!DBln$sUv8v4oMUqMSc4=M_dV8R4UKt4>d}XB8WTS{#5(TDUHcUWH=wE~ ztIZ4OI_)+V%s0z8a@BEXQ331>Sz-N}2U0q?F$bOTH$2Wdan0A{S2UsY0^qhyP#3YL zYvh&4oeqgbbrJt8we&?idB!6OFf+XKF9M;f z)`$;9EEi(o8}G6>MlLrN_7FhV2M~6-&{)^F$_iqh1bk~;+raX*9Xo~A1Eg})GZbYQ zlZD_2Hxd?tIj);Hmd`UPjww4+4*-~=!!#!m?2N*Sw=ygcM1U8;S;p)gHxQ05w2bkq z(d4?c&~0Je@U?Oss1$57Zz%kl(|x{}UYC%bI$;IQKNLG)kD&0iL8pw-H1rco0(rwG zSfq#w>XZ_%6f4QEH8IZ`7A5Dsq@R6azT(8ChXdp*#$`&A$tLgUWZo++3ACe2T$iCI zu*22u8!E!8As93qL15#d2{{m+(mHHy0389Zr?bPt15IYQT-`VnfcH5rLE(>ad^L*A zlpb@eRCD8_DGrW|Fd^zvAV8nTGzjBe50GIYVX=r1u?OSiLoK57y>6^KubbI69uCO z;0a(N;lQ$q5u*@15WyH}BP2%jK%)@@MuIWmi4Y|w8Wk!gDuHN3pmx94oMViy_4mKu zF?a21PS$dT)WLYynsbivHShbh_kBIr-Ay%?*t;mzh4!1z4amUGbQvjQ5%Ys#0`RZq z;)ua~kf^v33;61luP^HHM`~-hy7GTnx=RQ%cxfX6y{Na7&>g+h+x*EKjeCFJ7EFw-A z1<}~~GxyuvUi?0XS#)=-{AIuFmP*2v=y|yeCV6@9ejOwmp{r^Vx0T`XnRfVCE9@m% zA?GW#dnqXvIL5&F{$koz3)can9Dy4$AkbGo0)?x0JsVp(K6b_rFh9@@xq%+v$0S<9 z@^|is*>woAH{Nu}n+|!?AwOA%tX5y2z4BTA`ncOa>-T=z=SP?^&w(5BUmL&LiA7tH zBxIkH9`Tyu9lHSG7$Ce*!eo#GCxJzRKM*)Y9e#p2s8BnDQZ=@n=(Hp z`9yihw5Rt<*qQK~k7fQ$(0Fn}CIMV|p!jqow3Ywe-@Px!?}?-MBT!ras$LL#xn-t37MK%5(iprR z0zXer@&M^?Gm!B+SDDbjEIcs{n#=FVL5b{Ss{6P4sqsZ(X#XfCOxA zer>UD4IWG`>#3i3wH@@nHxNR=d0LA%xddq|K(Y;t;5k zOlGyW%9q$WSd%54X!c~4M%vfLOE6dmo*ShK15|{Fc{bjB6~Dt|`ALTye>xC!$T%}+ z-rAF;ELpCAT_)P)uo(-Uuj_??-0NHI>)AWc$f{A_N`k%Q2i4zp4?uZqOqaZe4pK4K z4Ql=)_K^Xbb$;f~5x_m4zUrRXVV|pifzI(yZr%D`K(F_bYi7e|$kWzO_i|my`H9%q z=7m-5(4e0WvG0JSc{|$+EA@-F7I!WlZ#v{nhY+)GI;1gpm0f=N%-14WKl9gqhA+hO zV1@FHt3F_UY#XQLOatefrpD~RkB5Tnz0!1yz6SdIwz_>s5$7bI$RJn}T%DNr%n3*4 z+(XHTnPaA`4(4G@IYkB#uuqsEJwSABM+bhj}D z%+$LH{)j|$I__=30w;bpDbOrI^*(m9uSQy&2>46v&Age=2Ut@+>AILbEKCu7SN?qa zNz&W6NUmEt7mIBJ9A_2}Tx4>OIVq(=QK>PPGbWyUJBlr6Pz4GPXO{ICt@4b3nn0MY z%Z8v2%zQV+$x+%8iv$>`rfnJhO1eAIhQ_Q6_C-5h&2y!nK49c-ANl`aA2MrNF<2E9 zFo1M zO9Mk=GPAzNQC%DBOOv|u+5G1!XNQLKx;YN{S^pPNrt>+lc|cJRKo8lHkDqndn(H9A)%TAT97r6`Yyp(R zvGzHLnAbDsf5$ZsP=d|7nekVvOt!7l_KQ(zExYBl$k|iOHhJT)Rmu^eR6e_AA>h*B z4rAhPEdblqW1c`W>oqW6!r{qX=NmI8YU= zlI+|9VeO}b_ap3LnKf$0HDAhTfOO!cGBm&l96B7 zwU%Zh7O1GXh3lg95(+l1WKVuBr2vJDz1b!30E}S=l34_D(PRO>tJC~H~q+%yx3MyRQi4ro9P?$JLBXlKjJ!hgey;n+rQC-7w&l!vO@qjUNNg-~rvClJ*_wLha$b{>!)FveX9lxSU=8NY+7OyKw0)q3b) zWGeI}hKicM`--`=HmtWXW6!>`z8%6s9+$wE{EF2bj$z(a#l!f{{vQB~y|XvUY1h8p z0VL&KtL0U7DauoR8&9?_?59?52f9#8QL9%6l!wRWxYR1WYp$`5H5ym{G2gw?QyS{j2yeaiRsHVLR)qMB<3<69Sb^eHh%kuFS(y* zFws6^!aF1wMytKNdWI~Pa)N)XbL0Plsou&QuyfCzHRCq(+OAtt67~J2J-}3?_XMRH zi?y1^Jv$%A`&(oFB;`&~vljPB0MD56?eSev$>r1|CrqzKOpEbu2*=mwlrbz{NXSAj8iCp zkbhkMKox#Jl|XX@u9M;M>ztn{HPY^$Us&2L(@vbhj$mQr@W;!*US4q3H;nb6x90b9 zSdFu`2bNOfMgj8`X5~C4loWA(IFub{ntOtCYC^jA1WFJ z6w9a{O0={a!+h`|`t&>Bq89zeq!Eyr@AgUNj+A-5?cP}xm-n=mLv^oJ%IhpDHuLTQ z;Jpg~cLlx)?R+2$8rhVS4+sVaDQa^Q$^e*OI7??rsY*sSU&nA^hbH*KXP&WGk3e&H zu(n^E;@A22_!%c)9y|QEmV= z=;lH2L2C?{9J8ePD0n8OHNT^Bjh&cqI{*am8tZ_p0kcNjpnNRuFnPnQlNi|+XFw@X zac>;25cb;oIbhnx3<|tVi7j_(5MvLE&dq0V1~j1OddR7(RcL+E))cu9Ql`6MdV5Y_ zJ4T1%#~u&M=No5$csD+A4mdzaEZ;;k_q=XRu@7+2gBYOP2vXi9?*2GHw1R*t_jn!qUhjxeV&ff_oC6piI7z%?g@C=??psXZ zW|A}hj_GvEcJ%jCz`;i6J$>zMT>Tn@+!ADQlb9#%a7 zr`@?b7`x}EAD@HE`=Ur&^D$@4!qsZ+fZ1W>2H+|vVUkE2|DIPHOE=PfE#T#rS-Ny1 zReiYvW=-Mv7?VY@iYx7mMK86_)bZ_r=o%Sk*q`OcyH{hjE8kL~W4@EigH8nICJ@D| z*Kb;r%XiBPPzoAHEuUpz1~~7NhuG(v+wS$sW@iPkZVSjLQnuH(_g}_f^5cEbP`zo5 zWTW_al@jQR5`EJlM&wP0yy=kd(IHt2KF{@qg1f`ZU!Bdrj$y(K9G>~-Fax|0Mh|0B z$>c*hI*G>&d{hXdgek+E`IiL56pGC2MTTw&_xw6+eT>KL>Vb)~jP?1jTnX58=JAO{ zq|i$?{0Nj3(9tP=>V-1*#N3Sni&ey+oJB`wBFU_gPz>0Jg(M~k+R#Aq$lz{Llpil9 zngO1foCx*IE!R<2OZ9;bhj%E500$WQ4#7S-y!yHH5|qH25bwVnqpRGJ>YoWnV^2T% zAC4f6mHe_3{o*H9S)vhx+O)7S3o})93A{CisyvPy!ch^*Bafr1yo{SUzl|B9}1{%0?y#*<1AXBtLR*FKQ%Q|_^uMtCjK|0^fKY# zT@38KHP8T$Ul_$)p+o@)geG){BnLTwMrz-_~DVBulqN+PM}x-nUnQ~4O`@Qg z`+N`IX|vINdj7h##2R2ccGg2apc8xnES&Js9=Zp=xRxQ-`z~7BT3K7`b`W`IA=mZ}6(V;_;nIiO<6Gm^Vd2Aj2RG-) zo$rkKzk3?9f+yAvZe0a_T1d!O61AeY+u*K*4 z=Fjk@N_%A@$T$>!*gOQV0J4-~N(`WRAy_v8EsofQu1s)8d9)_~9J9otE|?6YQOSoc z!F!~2DmFbC*$KA3pAX8K|H_rqd6gZKP5DDPGx}_>z%x75VhpYUO@ez(Fuf3HTSBjz zsvA*qFHX4mzH~BvOwqgl04&OTE+!;Im1_~@DUN(!0t;Ou6A9itz%%?*vMYde!OW#p z2CEV3laQD)iWums7Ha^f;F9vor8F{0jCnZ4ND18sFnVVkmQ&<>fbxschMt?#b3kQb zo(N2Rz3Xbq7SGw7NEc!Idw} z8OwRa0v#zX7}b0Q##8k9SW0z3+11w4d|b`LB{QmLj;o#Ve*^&26CWs!0M6y`O~7B? zGYoEhiOr26*Z_l5D>YL--=8yc>&H|hca+6TxfD%Eet#wAHIl}|Tmf7~RtD@2oYYfr z>l6P=Oxlj`*12fPfM$$~F*yS-w3;AIAi(@hX}sw{Acz8@SR3yW>23CEbA|(3(pb>3-U8{1^*!E_oQD8ejMDx`X&shNA z6-zQX)qHj<`D~0!XuPKGtc}+FkCfho6_z;@!3b#_M{bk0~y<=5#hsGhd?EiT>+q zqBjCE27H?%9h*6cAQ}+O%)L(eVqwT@j?@@2QLRVp$A!tMsKAy^>z;32pZ z9D)URcMmWGcNz5Kz5jZu{-ZwZs_t5~*S^$BWKvnqrg)G~gaF3Kzissimid#Q`O8ck zK@<#YNxS-=N-y`e^SbzKX64iaQigRwSYkRe{vPC~>I^kcF*y$-1+`*^wY6xBngyULC;n)ckWW`^2=x@>R zreE!VL+4ny!lXCxbRSc_aqtOc2Dz?V{;6E7Q!{H0xLf@~o8zxrBS}$}uCR`jt!O3+ zmfoaJ(Hk9pi4%lK6lE5P^TW7q%BmXh76j7D@moe`TW!{(-rJ=~}kmsy{ixE0jElwq-*&rO}f>Yvqi26$Q zlWN}BVy_7y(Pnnr(CLeXGW0d8=;4;(oU~SvYFQ48&M+Sq!-n0EusnbCE`aO`DPOup{9{{PAvA!Y5g^?D>1NA8lGygMDQ#lKt`6S&z*f_+hr>3?@e=3BE-} z4a$~e8`!QlZFF=*M85g&F zn8N4yt#11@{A~G}molgsW4nx%XALea_tR%j)2@UBT>P1v{^eX!$GqsVtEiBn?>R$8 zV{GrTyxRANj4au=++XG%Wxo2E_!Z{f$BORqq*PZ31O3HBZN&U!L>Q(ta6(gw!`u;x zd;GMeY>e8OlAk_X2wUu`0EqSFmvvvzTITZty-%qDIl&ABJmlJwO-}*z38J&o`~cnM z9mSv-?SX`)!SeSXj9gGhSKM06CNJNI-xdZ!+ofv{CyiftfMMBzMtcb?ht6a22)IW) z-Uz-*7sky6x}gVSUjy4( z4QHaVp*s}I(evhESg+6$W$;my!MAr!Gy^mCdzr5UC60#kFF63D=}v?d)4QgXl3~ne z5j+S(w&jN4kL#H-jbhSd<0)!abFu+qEZ;sv0BdQ&f)gcCW;&$REviGMic*dCu(mGJa_+$FFPZ-G%!^C3aUzVFZ-G zksO%(fo1DF;X;9Bkvo7g87yjXo)>?VLqJC!@By4Oe@ewPCq%tBX*aGrP)Xr|WUOUQ zkM9d^C2J!Ff>=L+5b_N_Y2OazblW#<9y1)Db8ZK3D6m~;40~4tBE3M7DtHGA35|A1 z#ID#Wtbn0hq-w==?#o^=y}{13EvzMFhSakv&D#(DO?O!b$AG70IP(Z7aUn>vK10Ap!%UgO6l^NU-un_qcjq&3h#pBCXj*v37rCi15{W8TR zZD~(H;=-uSl#KpjaLXD#dh7Qp+6pQ;(003Dh;6 zD->e$RsUlQH!D6_g8~P-R_aX0WQ1H$<2BR-h-#=baRjgMP|@PON*r|2Eiu$~wcrKm zvpoD6n;jtILHxItzjIKFW&W{Dn4A_?tFN3Y9x(RFmEIj7SjGJShUm4f^q9&e1JThz&c;|C(Gk%ELFYlFp1dBS6 zQ8Sm=<{?VgQhTxX6Vyv_&S1PCS`@O$cf(isSIdZfMN-Jg-9W&6_#W+#IhBEP@-deO zir5*^w5Zwzy^^`oFw^_f*C`8dhH~iefvcTBuB3_oU|?hDj@MZD#rqP4~J1K|rKR4;(e*&szf4NaRmpp>+B?y?OC_Ju9au}hlH!1!{Fi()j zpI#LmbW9+ll_-NQe6@Bn{2TC~YLXC-#%J_?XKN%wTr)7fIe>2;>6_yjWIx^jW11d1 zw?-I~*rjXlHPzaqkFcOKbf`JvjGx>$=ba8@^U!02ZTPvcbc zRk+EY-w@usm8(DVQ4-ts%}mv%#ky)%Rx`-!3;YnO15m(OkJOiKXL^Q233qT5V8M{q zFoe@VEmk-#uF0dLBUq0IJAui;GMZMw&-ba&5xtPOVEXmTtH66Hoc^1*FsD3fJ{kZJ02 zY7qv&8)(liH5Lbj;K$mmYggGMb9yLOoh@qy{)4YtFnmcYq9^5KaMFAU;2N8J@H|W8 z{aXsFGtoIZ7% z^DU#yMu2?emK$|l9x7}p-v&-Fg#EN2Qjjq8H2m{n zfKA==prQR4PNV4*Hz{I-tR=d~z_dsnHD6$v+BTCMoey6cz#+TG_dbW)qF|`n&^}es zx~Sj;Fyo`Jm(t8)rq7GIb^Vj(Sz&yB%Ha;v_!7yVR}#?Yx=j$H-dBoDVl^DY zdXKOKK|RgChAP{Hd0iHw12u6H>!~C+>jhh}I!dn8kO3FeJ7}FmL^!4{-d1s2TPg?2 z#6uAo*DXI_kB~`CnrZ%YTV*%Coh#%bTW-wo+iv3Vy#hP<8_e^W5ZxJ0%0svJXtYx| zx0k-<1NA_E#F?@OZ?Tj|BAt&mHQ7^&J~Tfx3JcpO#hPJ*;+lhClXBprNyEjr`8e1? zW?_5jh=h9at5UBdSYlLb0l*1Ar>#*Yts(D(GH1@fEPgu?`m-Epc*F>0>-Hw#HMIX8 zC|}}MXVHs8h9mLQ1_hu%Xddc+*?cW?<`maoV`sgv(NhW_pJelAmDhiYl?a^q0zSVT zOR!hk-XzIa=iVXbwZv@rBwsJ>_P9aeu@(S?-*ohT#WV4t8Je6HXtOahqqvHf3mE%z z=OW>1J`+&Hk})%%c3>d(n2B6$is8{+z0ZpE9E?$l4e;{KAS^n&>es7-7KQLt+^ygN zwx+n^wo+OVq*mgQvX#`d0%kWtIy&m1Dy*@9sF5@7>c*munj%Fz0S+_7=XtjQ ze|>mg_7S2DRV;<}9#J9BJmD6zpkz5Z;i~wtnsJjcGi_-yF!1>^kt!1T;D@L7GvKTB zrl`-qDbozo_DeWNQ?>xNs_~*K|NntB1e6vDZ^XsV$`_H%XS+?m?t6mmMr2m3jKplO zcfG32&e`Qx5*r$SKo4{v4#bsEv$xW`5ua4|k=+F#i~xNXG#~AG764aF(3_f{i}9~d z)=^5rGP{sRRLk%E{*@(TU9xKj&SB19;UZ^E_>ND$9gLO=QCte>-9lzbct(a>TT;I1 z7Bs)u@h^!ufyR_v`$+I9W}{pkvo6EN(K7HjSHy-=5?+7B)K)m)Wln*0Y~~^Ca91?S zeoGp9gdj%5vmAHLCaDpq*j_eEKIqBv<6ZIo{N0$_Q&rmo`BSFbX&=RohVa6e$EQQm z@F$!oO7w`^xWE*={xJr+6to+*S;Y>2*u>&EK9ZDMT3x4q4u2ASNt=dL(L)PAHHt#< zzxjehMf+^=wH~{W$7@U)AFdzD=TR4qPwxqKR?9?bj!Xs$kod#8VDmd-&G$l?4&U~T zi@rv$%gvKpmJaUm()T_6o{Sy1*9mzww z$fea?(ne8W$iVG-?N8__K3YE9^5tBR+H#4v=n6U4GPSXa3J5E{InQbp-kpQBt+6ZB z!-a91w#-T?V*`ZE^-mvL?155Ovc%yqY=0wPP`>G6a&8dI$k<`)7nr)84p+EGcK+13 z2JR`W7Ce1BJa0nH`x0>$u9;jtay1%g7MBOXF{)0*1D2umTLhGMF-?}Ob&u}O5 zc92JP(*l%Uge=Ng7z&x*h-r$2fSja&A8RoxlyWO6k|jzEnSo0K;$Hx*c>mg!*duno z)2zV-bNTM8Gj%F1iCz6z5x^V_RmO#7uxyU+J0rfOJ6S?}_?CXYv!)I8E1W9tdB{-v zsR*?o%6d`Iger;@LU*55j+S!HA6l!MmXNEmfTioz6y_k zC_mvI!GB1}ZrJx+A7V@OU9&&y8Ez_US;t&CC*Ff)K6yB+9OwizXQm0B*l0`;ThqO_ zN6Wc#Q*ixcDBB$(wn*qoaxTf8-hOt!U9oc?Vix09+EkjA{%iL(nFB%zAm#x_UG}&9 z_#N!t&Dav!5eNz+Ejt@Vg5D528FT}^_~gs;;xXmC!J?&Wjp}2+m0s5wGZFz^@C09M z^wPwV;emgA$L~(o{97LJwm`waj^v^K>}Lc&IK`=V86nE-@BSHs$~gb99ujQ8r@c9l zHrFk}-<@)qiCR~SesL%&kdt?fji_`nPFEip2i>7EkRT}8wc;{5#k*}}t&)iylQUQ_ z3;a7$VZKpF3Cdp8YcIRq>I^8ZY+91DvZbvw+!+@C73hzGF?yP6{_c7V2}4=K?0b*Q zt24~C^WF#~dXot=+fZ6&i;9xJ_|ZQW4&jqT+cAs#Lh2Bg-Z(`TG}K(LAF=Zrq=Fy} zoL>n0>?PsD*i4g)u4daryw~BbCU|Jm?HOoN0(Ck=HV+!mOuuFhy*oW<_bDPCCK&up zGP;+eBds)^@pZLzrJ8d+t~a)HcXf&RrHlj1F6o|iv(BgK*4(UJU(g-IggLRWfv!xT z=GK^NvvHhr!P^kS$ZR{7k3=Qdw+zw+ckV(PBU7fm0ORJr0N;K#A%7jTsTQTaKQsH< zIKi69>)s0Hk2}X_e>@$rQIwsD^znm_K^E9JDz7TMZ&@gYl@E9Y3%@0h7lj%JtwuMsA+N=P zy&ETps0U&5xyBmXA3H_@pEL5jb^SulHG4-%Wf6`Wy&I!z^;9=VZpX?)7 ziD)y9IPA=2L7I{SfCA_wLvA9A#pNb_=pxp+B(iiH?LSE4PjAUkg?Zp?Bz#H&usMc4!S z1O@_~7(?`9-m;^p6@1@noED-R0+GJou)Q{Cm&E=%HffJqLLEacA~dNQ4~XH+lXQ!h zz~s3%*}jbyn#f~&{o#Cimh12YpJI4|MgaXlnE{D=CODPHku4DaGKJWx8|(}%lSd)o zrcNb%%^#;{V{aTnN)~X8d_f|E*ZYy!ZFfL{{;hOP_vCXZikYT(Rg^$<&JB*KH)~bM@F;-qBpxxXaL6HG{IaK}Th;uF&CmN~InX@}y<)P8|o?bezUa_guXu|R21KNPs z2~7-#^%#=3%b*4$&LBm2p2W#<(=gb11&em`stS2D+#cFlKap)ti290Z1`fA!tntGC z=7JdZP|2kdp<|8e@?CkD$=OtKIZTk~XDF|;gqN=BP4utwd>NONdmTvPw6?5)^Sm<% z!A(h}r%65=HurqGAX9oKZ~C1Fg3%Pgoeh-WnG@AMdI@GD(FCy)$6+nlINC^RRn1}* z^tjlLRz1=ZW(uPnRyt_^neF5f^Vc0CLx2~7Fo(05 zq=9%E&ZF)0?P~;eB`IV@r1-RHp zvc@N8>uP?Ok%O~$c=b7UD}n)4YEu3l5Y0tbB7rKit=YLKFVH7Xc-t1>a&O26G{y6c zV4}a1%HPxcB>W)F8XCgXG=sp(OE6iX>Krl@OC>lGV@98y&@3U%U|XXs4?Gd)**mRx zlc;$W-80e>Y-NkQkrNWG9wAH&CxMsi*)xkP{21Sw#!~+v7K~`7Cpl3lE~?vAVotT` zxX}RoSd!e}2vDX2v#Xwo9`WmEv(v~Ou&1UN2rQltkd?rB7XD+V)_>efkrX!Hi457b zNuBq4bHn0c!$BG;t25Cpo2kpb1OR%sqCWD)r-)mLvqEVuewlPC*!@TB4pU3B8*2x% z;V6V=`Y^I(EkKw$d@R^fu90JulRd6_jdJObRgbBg|U4RgSrqrI9*#U}#ir z1!xYX++~EEq+aqm-&i??5ME!`iKH90ph+z8#P?JON#NEX+*m8miqPddn(}xBm)v5N zHi^Z}whc`z$UF}DXTovUkdBKW~0R{aU1K53n|H8)&YeI3R8onn-I-J~_% z$M9NQ3W)N-#c-WU$uiYCs{RfW7C&O$tF1kYAJA;4ZwK5LJI8_$^LO!%PIuwD-ELt@ z-H%IK15=YQ%{2Qxu<;54A5u4~QfyA-e z`Q_yfkyCeOC5sit!ehUWVU|~8$sn}x&&MIffzbr&P*o0HYS?YhOFx*jVYk9PtrgHor}EUVY+|(I+aAJ^UR0b$4*^jQsA4A;9+}Uvs!S_sYUW zIg@bmWQeqWsX<5KT#A97*=8cn3uy4sd>Q{iL%uO*aS_S)J}^|ist9Xl5vw`=y?66k zu-D~(Vwtxw)b#vneCb!sL9kYZR_mn@aqSXf3S!N`zbw-yu1y@OZ=Q^>d7<44KNMb6 znS%^wfAzT&`^2TaoR9B7!&JM38SWL`7C0kB?~*6ToF0OyW~7o4q1b5((K8}-=YvS& zGo)Zn=T;l5?7qau#@>GZU5O3Lf~5lA%qq0lbzy&7b(-}W56i8Ih8vPv-ABAyNjpAb zm`}C?#C*Cf$E0ApZKo(>eU>DD~vN19+I1TV1xbVcvN zC7!)v&Pnj6;%`6-XGdgY{PJEYSYKgy&zH-^#rKtRa}!#O=M_z=5oSB_T!IgG3pUi( z2|6a3e@S`xerAUXfV8ESms%O;5%~Z;n6q=4$-Dxxa0?p@<**B%`*BK(UkaUuAND{h zw^XH?=x((Pk?@C(JcR2#yd1=wVPL zyj7vghjiw@c|ea<(Pna6U?^O|F71#FMAIHV4{IgMef0>mm` zFvdl!Go4>~*#Wa^^IW|YFggqGTa4>Hp7k2R6V>i&0QnKh@nPfkZweeSJFZ|Op^bxj zML<-**yZg@CC=5(=Ac3{Ju0;G0WUT(G+w6t$8N%cf#4*(0X@O#bO}J}N-Y_Fit+e8 zkzd)Y<7U=o^>~JuTaxBsl}$^aSd-%=XUtT!#YEMUGu%5d@&`D}COM<3swP?Mq1A3j z6oTnZYy~uEGs)GfkqqW1ZeZ?xuU(Ze+=>z2Efy|H05|7cCi~J6@(NsIT=c-v4pyzh z*}%uM5n)t4=xe&FokTsaW`9;ixT_>cu_U#VjvW01d6y+xTUK5b!t}rw#fhr%BgoTw zg&KFN!{t1}%$ak1O{fDA^;K;3CiFdX4Kq7s7>jB8&@D{rGoAd+! zTR7|f?{W7pabV}l$dsu?*y6K=W>OadRxQ4uq|G1wtDiz@7=qu0!|-YkWgo6M$ir1gAHd?Y{sPzx?#e-$nj26diP?AIHD(lM}58ye|04vDr>nI4OEI z4-?ow8BW)x{(bw0xU`9&6o>Nx)z-o#W<+tzx>^h`&@Hq%<+8t!=(`Wx0N%Ixvhm}_ zK;n!d?HC0a{D~IF#)<|`&E?QqrBan0YYF^LwDar(!n8b^urWO}pBoQIPXN>i;n+er z#`cZhc*uy0LK#j*Vr2z>L~r}-4;nemo@x{XciP^bLO=pMlN3icq^qQ#l3ny!t#utu z6}IkyiLMD~a7Hl?N98mRXuixP8__P?$hNHI91N^7DdiKERyaqWPway&(N0pK^*sTOx|ZYOFMUJ5@%lR3b)*Sz32B-|?Kx*d=ngOaVPJ3wbz;wV zM9z30jBVs_z1;fKz_}Non>D?6>Ic73j7K<+pc2u^g*Un~{(_Qd z1`uaZB!f_Y zx>1k9hU!6!d?(l%UmmQeae}2kgF=)Af8jn2zZyX~3M?359=@Mw7>hK0Usy+MHcLVB z3T<-}6}+DR<|Z7(*2C9b;e|hHw{A3?s56PeP1`m2#mVw7=RW1PD#f57Udi4Tb%G57z%N7DC#Lbz`5){yexSwygf=h_`9aGaYS(HV#P9kjQJzW z(m0x)Wi#)hHs}VoXHq|K#|juT%i^FHO7Sv^o2wdWo%rtO6fx40cImyY0ly^8i%+V-333j=}o9 zUz9$Os7K@aTIMqE1gT7OC8nY=18DITz$X%dTvFWeYH1J6lUj$>0wVCu0cy;Fx)X;U zxje=~>*80F7Ja1<=g;WvcN$+t2ZQLpxW@99hV=*2UcmD*lVg|+`660s5WS(Skk(pkKBt1YbYN5fvAONnQmP%`*&Upzz_T3d%Wn;Wlb}e73SS7?X1*5eFYj z0|~Td0(WD5`yHLjS)H`#J{-4b34O6h8a(FKKT%tu7@^d=*iyMeN5AeuL;K<~x>HHf^1uaxs zguCz;V|RK8;B$ckD}j?WYw{^~{8sppABtfx+^SuFmPXZ#9~5zm&q+i-jr`BR*$bae zb>pXnHi6jeLCQBti}X)UF(7A{qj6=Ve5KPHc*LwYudNX6FUwzzH3M2xw3&ThVB`w< zn^(0T&`SMo#STMcx+^}yFO%2Isbp93at+r4nucOnABvGv=ImB;qCQuW?xJ_yoxOVE zLirWieKS&yY<=7h4n+AjP_RFjI#9Mgb2j?$_758=y{Gb&gQJaT*?nL_D^UYZ_1m$i z=h~6;5%;W9{Gp`lM?3RJn*psQVl`LMRi+QV-KaXkf_dX?=L`+2z9e)Kdki`ROU(1r z0cnwA1^m0cbA;ZjVD+B?o(WlSOVD|n2*Vy3E`4y`Yxzzf$SL@2KGfU+qbAhYV}-0L zY@D}i(Hj-aQ|x+@Kbn^}=fTCVbgBlHmq`E>KB!_;?C zOL%%hkYqLK2_s`(f5QRNs&<^^%f3E~w@CvJIr6fyi(>-=go2WfDANY_PiOpB(potO zUC(3XGwi}G$YfZ$&09HH^oq+JkAb;^Bz%AJ`j_-jOu597n6%P~c?7#ZSXE*p86eWi zO5WR$mXKn0;a0z=Fgs4}F1yI|FZ;Q5!#8y(#1+#2k`i2efS#|RE0%ZpRh#aqLp>i9 zGbScQ0gEw3+zG73}qr0 zk{Pv&{#Fl>(b#FE>XBd7T&%!lgr?ATfY^~g`{?D1kbi-9Jk38aHmgf5R3@gWDyP_A z!{_W2yh`u$CjvR3wX|xSqikK|T-cs84`gjS8k4gcK(9^MFlEu=soylX)H{~~;lg*y z+b(e~<^s!eSDWZ9+3uL{zcAj*EKO>@7JZVhL+`D^mx}Q|QTafV8O*a4_dou2l=;aP7vw z>q;28kzmsu{VL$3edH1IxH53CLi^AT+l>+xOz!wEP5= zfx)%v{W531;^97g2bz6GKv(u=$;W3#p0$Z#VhuYRn||*8;CqK-8!!L;vmSwQH)_0uRH4M$a^JSrF?BBX@K8bMPUyc?3GYRga)yyS+71$)^dFEUFB3up+SxY#c189ZviCAmJI4}5Ko-f9_bx@j= znnI@&7%uU}JJ{~NUfQu29j}Pj5c`Bh2|qf1h>H?f!mLBrqf)@P8uG#JNZ3>KM-Tq& z?4^v89FmanS6%=EtRm%H(|F2Zd7NZ}&9gAWUP7__Yr4y(8jn&1{j-7&^%Gi)N!+Mt znx{E>`u@Lcj>iZ5f6XsMQz%SCACMco02Rl}@|$TxcC#>1hY;pfUlkvw=D*rAQ}RM* zyix;I!X$nA4>$h!l zOWSz)J8PCmFwwa{kBIOa{zN!2Md9}o&r_$g<7Lj_6n#@h&xS3f{q#_<`h=6-Adr_= zj&qDQlUlGYmrCso>;QZ}yE>%NE9d+HkI)m0>52qv;6-uPSfysvcHALlX~uQp3#MP` zRGx;D!4^b{m5vK4Uq|ED$d#xN7n2)O#+$B-RI~n}eWI{tiVhDqq7fY58%nzj^ROnG z_%76RSTNpLQMb&gM2ahJgQvh5k|hY7HS>8C2!bghf)u@M;05E?1YgpvlnI0Sg-Ic1&nytGUG4W0rX=GSrBL?h9+9h zz+W-y>k_`KH#P*3$l%t`p%E$f_`ifG&e5g)NJxDa!ztTr4zn-+$oXO&8li_ha*cH4 zg>pO|2#4!;PstgR2+4y5%oK)JpK7WpD$V#0cA>p<@Afa>+-^61q3X)R!t9Q$3!#vE z+Heph`xIi6G>(xOE#ebe4VV*5G?H>=9c93F51QO}zKA!>#WC~_e#w+Wnu5RN%4Bz7 zK)Fr3N7);^9E?k4L-TSd^Ga!R+}HYE5HPv+*dBzZN#-H+lCk1#?SF<3Thj*S4^2ye z0BSYnGZ4hhI>s^JdffB)ho;JTAdAd22RJ|IA8E?V?(k3B#n1{YcEIM$x0l9mmxlG? z6=g!e&&Yj^idCV|Q4w7WhrkE!*k)*3N2ilTDiR;!LbJObd-C5PcZ*@+f9yZ9%u5^L zD)a%`qac@;cQP5Xu|drQ4R@j-+uF5_p^oZ~TEmwRSmI6M$Vlt*q4a4sC6xKCTDau` zWoRfPQ0yII>n|)si%AYso6`g*ZBd3-g8(a(ISc?BMyp@*d$KEqq?;!;zD7bVP|dBj zu>DExa-N68VSn3v?HZg-L=2!GR()v+<4_M_I0uWmOk3^(=(M=e2Ll@C^zWJg?S&dzHy76fkT z#rd%v;z3AvtfsXzh#&Gd$fM*VdE1;3oG+GaYOw>M=ea&;EvRZa(?LTzGEv{fnoVCf znOW9QF0Vanl7#M@j4l3&@>sM-kJWo2_-pSci%`o_qoiAk1#>hkqRd;-$)Td)Cl}Twx**} zu^0;GQpS;0M6_DJ#8i?S`NfQ@S=3#|Rg=mVX{bEJ7WI%(K(5eEVJoPsxW1d{V5QV^I6RQFH|Yh8 zRAf9ozI{Oid7M^%+no?8%0JS#Gbn9?3znf#(JRu`_?VvjjT3Eyyhi&>IlKpl=Hjq# zedz=)Z5Se}Zv@QL11}90HDuua9O6Tdl=EL7WFA-eJdPl*@*;O-9Fx7ev?399^LHCh z8}#FT`v;=1Gv`D5A67ME;`NU$76~M3)~Vxy-t=whUfhDi zaXw?F%deBv5@bOgJSD=oeetjJ9mU)dG0)oSC?f%Eo6X?{1BP2Wwoa;jKhoZosvTI^ z@W|XN#k7pHhebFQSmDW7P(CC5(4 zk#gk(_)?Hy{BEf!T~WZuKbAbe2OQeSi~CpolSz$g-T5BGv5%;WA4HkKg%4Lb;76*7 z!Rz7Oqjt`(hX0R(K;Vj-hUP($yb=qAF@QZK-OkmzHe5^cgCd8na2(042fX5M@s|(} z0nX;ukF0DNy`xw=OSypqVe5XrprF%kgyWMB(PFx314529Io!rj9vcxMiIn;pMk=nk zdE`?;kACq*VqfB6ramtoQK#rxIX z2?jVz7wLvdFM~)%1WxuAKA!20y{a4Jv4l+8^V`t-G8moyvi4+3wy+|O++6cPMbCe% z>y-&v)Ie2hul-9oa3kC^-)ZcFK4g7bugRV$+GRPRTYUH}ZNhq>^@WrlX$z(jT4^ESFYF{kYXI)BgmCYNb zc>1H2$rEtEfJGauy-xuUv9@J3J`XluzHa<%mh1;8bY~#xcOv0NgNCFCx-q)*hi6Rp zc6Z=s&v+Ehk?4>#ONH{gbJ?U$2oHYs4fflH=3fZ$-&oxZX$`@CJ5ZB5Xxw#M^^FLn zF>Q+EbA#GG5IM)V1QJ&)?zfBB0kHPuL&XH1`n;8+%OC7s`_ddwilQD*UCiQ^YaLUb z3xmrjp>4h6sqQrxrjvfzA4%#&MAsKVT6Ph2otZmziw zL+;oY;nM{jxKFRgV+;zFqA11FJs&I`KTJ;R08<-UJ=w{>muCfjp(Ml1Yeo2MIJ)o$ ziHA}zwnt>?brs-!G-AT$-rV8dc=k?7*a!7}y6{J@=w2G~VfkNmTEe}@lfur^a34&y z{jmA5F53%c^o`JKM=%1X7yg4|-k1p0e~F7#SCChE#vpUui6sa$2AV0Ny(95^?L|pa zCyCLj`EhrDDoAC<$(pgnxJ2Z5OvX24FSY!n_1$oxM-1vvglv8Pp%LUGX-1%UPipDi zdwBnfvH9!|2s#l5q54e($owkRa`Gbhdd(?%2V52o<#@G5E4{3>y;G^~Z-z7b z9SoHaSNBOBQE-g?g0uaJ4(!K0SF~6n-DDy>V|!7ZMK!*D1dqsqH5L{m^wIKS z!&uOL<^8SxK0MU&3Z1SfHHLzt#HM_cU7Tza#?BVLE-JQ9Eu|Y2Z)Hn3C|KudG*}}q zO@D3-=O^q=MEJcQu!Q;WGX`@X3l(e{${{?av&duShXSsGd@XS_R*E}A;sOz&cb>bV z;2a+??wwtUCjnoreVuASW{Ox?K5B z6h?Mrd8sC812&|%#cM!_OxkW{n!l`3-~V)HJ=Q;;DEw0=uD~;!nndOQnffnxiM!0m z25TH_HrEmT+wJst_6KnAi4tjo{+z$wZBodZ`9<_cUS7A%t00pjQL{Y1U-LHtQ3&Fh z8_T2JpTtZPzEt$CyLTf%=6iHZ@;wW%5MOU3$Pc<2oG z6|1HF(BD%1dec=Y)FzDXjglNuAP&J5Pz%Es0l{Kd>Rp6~qn^!9hhJddG3uYCz`Jdz~8X0s$?u!sce=LCwYyGmWV z3WESj+N2!SjNMx`?7TDf*<&Asf4RNR8$Q0Cyy?myacKH1?`YcCP<%w(gIV5M-xov6 zw?s6zw`_|4JN`U}95W|h7KzbM6|U6GJ{5y0=I%6nm6WAUgy29vp`>^WQ_~Ec+i_i& zR}bwf$8hi^Qd!T^e#l?o!?jK>Im`p;&lfTvUS^3~m|BHkctx~aOWgw$22Xgh6(gBM zl|uR+LE5DAH(z;}%AibH(L+q{*yND}iH?5HdP61*YX>>Vx5{=@rCe;M6S8+(Bj$}( z!Az-yg!J4c^j(K3=j(#=S?WV!t9-p$Ef))wKsOB>gzk#Hi>$b4<_AS+#thrNLpR>W zXh$tp9TR~xL+MlGgR1VwFaJt>7X~^iFM!zCm(Ba?e5;6D+oEvfOEXGIdFbf!>BjRu zBbzSoq>UhY?+hTQ?Mq1BU8BnRRgVXjaq1GMh<$yTq>lqkvkPD(gk+Z)_>X}m!FB2) zkiWoqiBEPy0}&CDY|%&3xW&`Zf@5GJ0SH{?FtbWvVP|ZKew^7>@G`zDXvYA6NT|o@ zL#JU3#Xkv15WYk$RCK^**py@ys$ZMNU7WDyNTWKl>e>(#;-@?vB~LY7}hiIZUf9lVih1n+`R2sEqY$8iD9NPTg|F4>|T z3zPk-+|&yT#?UsKJAXh5kFYb(;?*Zs%)w=;cDTz`Y-30pV{CMu3+p{#@DF&8$Xr=% zE8wlH-t9ycE~Iy3h7s_O`PFQCJ%~Y!0l`xQdV$okw0AX>(Aek_KR3f1Yw2wyG^KFX zIaW&DaAiza&G8ly^g?=R?iqAoVsDH(-Qfi{*n z}tS2^J#3ygD`Gx;ytbrV`|G_^690u_C5S)QDpdQLpDHTnVRn zSCRMlKz|8%=R36ff*xFa`1OMN%5`kRVK)$himu1RxGlSq(HQQ`(p7i@8*mOSirrTQ zHtSMPa-AToBm90^MgR^{x3@!b;98^=7U(%}^ zB+zq49hON&i@KlH=Lz|nja zdJ)rvHtGAgK@)_r`h}UAT#?D{%k3_9sASh3Vw~0P8lq}r(z*M)HXsUkl?^Nc0%J10 z!NFUai=uXJ~)lbbfH;Gs& zRl&ixl38(7Cfy6kaOC?b=z!4YS%=OfaqRQ@8&d++|78JCQ`3u+y=574Z!s<~c7s?O z?L@~4c>8SFI3dx&SKV3;)oG*`&Z~R`~!>bWk>=8s!T=y z(C4F=`&sqZ22DnCR&7X)$o(zs`%*Nt}GB;{LYFS7_Ji03_P$mgmdeg>FJkrJ@$a2bbsC2Q8V9lu(`{FRxHt4Ojj*8~2% ze#TJt{+kXl7jHV`O@{6%Ee(XG(>T!rc;fTgXI1DA0#FS9Vf{pt9zm_tpZjh0G!+}ir6Q_^LdM*BgqKUrP&1y+zWI_XpYk} z6I_CN%{MA`U@Oha*>e&a10O`WP86B19|-FNc(pb0aU-PDd^_ymh+@i==`1wC2wM~P^AAh>Y{-eQV!mJb*eIax&E0q_Wi_pP;YN|={ibxC{T z#7;>@uV;d~@ti5e)cAiAqqfZQAI3&lU_6Jl&Li310dugvQ)tXplLh)7`RB@?WE zZ-Af7(#_w6qtAL686&2YQtNOSsm$$`&n?sHC1!>{RR@Q&vAW@#xef$SOzVK-%(eMx z+ya~Y@v4$iTbHOzKLTkd%+;ESn^W7cFqr|pF^cqB1&kTZK1#vqk95M?pCh_E0S0q8 zFk0IRwqr(9x-pc80ZP^$z*_K3a}`r{asZmN6#9E>?#GO6tnY8l$pjX-vGrMv7-09%jN^{PE1aAoF(Z)B##*76PTw)83WkJT&i zBj(G03j-B6$PZ0FOJ>`EGh=RVf7rddf03y9r@fl$jA#38BEyIEGj~QOYiJ-cQ=%pr zryn#1=0&>$Tbbume5KZ{dQ1_V?Z$lA3f=;ZjL(d+_V^mmvo22~U^)JvnCY0<5*kA_ zo|mtn*O+9_<}?=hTIw8YWqeS5sslpRI7XHMILX|u{7t*cwYjzClP&?I{6}ki)`9lz zhxdYl^sXAZYY`D^hn5@n+48U4PAZx{f5()nwroDb{n5V2U+2bI8&%b)1Yvm!x8z8y ztbg1-^C};~+)b?EB7+YCDgsuO&x5C6ckUORE~dH3ullar4${do9rYVo^BV2^$;uq5 zo-&81+&X;m8hC3x>d%YATft{-i>-j5TWh#m=RT2~Z5@<6eRB)M^}2E1iV$x7o&w{d z+N<1Cg7fPoK2pl-+=6kcG@_3c@wbkMiZDF!}Lx;xAc~lmzo{U?yLn0ykz(rv;cIV>PKI+$iNTjFBE>W*lW} zv||d#-;Dx0VzV|)y8g+FG75G{jtjU^&iUPqnX7RTFwlK2OpJly1|e3$AiB3`RCBd^ ztUY{+tj`V=nRQEie8Rrn_<53RdpAF>#iz_#oAm)e%xc7HpgVRGaY%_;KR0q{#2m($ zCBJW$f(wPi225vg` z+%VUNF*nM~y-uxr0@IDJWqNQ3TtGN>9@q*mEprBdcZLEQ3+AZ0i$zY(e4joqa>Zhr zg%WqaEiFp36nj~}=a8j4<6CLW53&BSfXN=RsO^_|+;?hrhr|1Fc47!oVdG<2nwnX| zo=X70$=032QZ60@nr9jXX24kF^PtJ;5|Ev_)va9@zQslJlO#MB>=(D1zzPuVTkbJtp3Kwq?gb^?GSV|@B&j}EC9#y#CM z`!F|)#_~;vyy=j?MmnS=_&KiE?fW^t`7?YaGiCxH9}c3%i7e+@8{5XW9hflzt^7`6 zAjqIyrrILs2%Qp+W(GL#fIyq+nmGj6pt2|$KmaJYDq|JPfC8GQ7nL;u2n26nq$`%} zlo|D}{CBJ0`OAKE^{4;-U%vV~{?h-n`n`YbPp|%&|KTsJe(&E+KqvSBpo)iIM0EyB zM>-Nf37b8^>L2e>Sg$AaTPNECMVT*BSIIb6C%#8c$p@gY;_`u@TS$9%k;y!H38`YL6XNyF)!vw9JU7yek8d-6-!08jUm=(Ldx zLYMS5_JiWUaC!;gp^%wmD%8EEa7&Gluhp8_*l@e@bp-GzyX}1f`{NbElJLfa0LuZZ za=)D@?j>8l&l&&H{B0>%s$W!I&@@ntSt968-}p8h2B0y)Z2+}CTLfP|G)s=R#;#Iu zneU!C6;iVC;Jrq-4E$hN-*V!0m`oki(rDhmeTeo5QZ@t4@b3( zUzlX~6ZP3R>60~O^vtK|K%)?okn?%IiPZwm9ACPVgYsvUN^3oqqTvE`T3|-f`z3oG-$QF5 za1vv75gZfyoat^!Ze4%v1TXli zI)|{T_oCGLf_O9!{YKUVCC5Z;2V#RMHK`y#9>uRj;SmE`9U&i0r)0GpWN4)sC40tbtJ&n z?{3}L74)ICJ8NKVEq1u*5LEStO7xxGzpF#uxRC&61KzareJN%5vQ7%9*(aV6%Z=5{ zceVp>ZXS0)T*0`v#;1~iZ-)2#``4}$Dr#(Hh9V1z!uD%-kWMOMy z>yVR`!o%kE4gcL2&+ghAs52I`dfBV{_SMqgNvq=?dp>X%vZkF`K5sKKpIOI-Iv}>L zHl^Sp=weYjZj@?jdnVtwIoytqYxBe1#$G>S443U=EMlx3J~sKqSW6w`0;XH*ZQ}sD zwcZ1hKbv&O6FF20rQ(cpx!93sxv8AUnKvEsrbGT(>5$okpX0AD6x^+Iz$d)(_e!ZJ z9wz(zC~t+$Z9G#ndqOgwC|Z5MO5!QA#Q>9jNvV6U zz=$W3C_$NmxM)KT(_jA&f5qyz{m7qKoqx|Sbh13Je)Qk@^{XFMa;oc!r6~Q=!ZcF& zfdhgkF}ow+`ZtBtsdF;r`-#*9B`94Aw8$~P+UUR+7V&1-nC?vgFoz}#&cH}3Vsuhq-FbsEMlmAJNAoM%BE z8bDYQvSj9%g7rPW!F;KPyC9&h7ilW;H=|HX&#@#3cItpEwv*~Xptr{=H4vVgk;AC(qqcV2205-l_g<{<_CDfRDjEe){!E1Rc{>f9^g4 zGv?LGX$9QMVOEnL2>E*Pc=tL!+InQ_P7&O>_gtebmiHyz05CvvZOTmOsjPN^AXh^p z3blX>52k!NCIp4d?dYuLJF|3r55Fi`_w#+5=uK;(oL*ap6Sgy-!}3s&nYdqozc`6o z0TG$UT9eyM%1n*}kYk{{Mgt5WDa}Pr=lA*104g(JI{Pu$W1tG9JJn2#L(Fph*-SMR z4VBcj>jm)29DWKUXlG22k#qaBvS&Lup!3Frs71y(mdQK?95FM2ieW#kuM!mZ-6c}B z<5IqAjUTqzI5mPDH?rclMmsF!bm0awmKXkF%RbK40JoJRzjZbMI#aT>6AKySJea$- z>xCk}A12CuW`&qTV>wBSt=Tm@-xkwf@KI?@s*Dk^T5W&8zkR2X3LI*=HkRHaK-7V% z150aZsVHL%i#`RC$J7W^bZ9AvXm|dqvF%XOXB`3{qJ23RS`!XnAFl}tvR@`x%iKL{ zQ-`>d!&dGe9d5#vnLTYP-|YvW=PsF{UTSHGVuroiKDp*U?7#AP7MZ;UWbT07@^0P( z^ylp8(?4U5m9%8WJEEG`Z51h0|HMQUGw&c>)ilEr77 zlhuMUx~GHjp#!o#cjXg$j-~BWXvV7h#QY{(mwMqW2oAfYpE<`S8q=RmI;8aRCSbt! zkq$|ITz2mlcg2e2D-ny;2{#Ah>an&#Djq$oiQh)i zP>h*!w*==Cv(}md$r-xZu6MC2PW%@P$|kc~+QEA#3O9%EDMC$#Oc4mfA8vV{^x(^>bL$S0S3~h9RJ*Zvij$K^B-G% zYyCg3{>sJ5lfBJ8)e%+V<@6{jr z1OM*ocmI*UxcY_P|EE@e=x_W(t8e_ipSSuW|Kh*3`s088e_Q=G-~X#u|JlFyFRXsq z_wz#kc&D zGH1COq?R{)-!Ag3y#Ri<9W=D}2>is7HK!exV(o%rYrrnQrOaymz5%SJtW{BvfaPM& zYs`Rtf3KJu#~iQSPk{R!+I$&f!xl=xi1*n7Ei#K;Ip%Nk)5-epzD$*Kt z%X}tF>5;{C`~|Uj+_Q=b#S8CwKI^QTWXjJCeC9>`V9c0UQ7cAOZADig- z87uQwzoj>6&-H#+Z^hnS1lHvL8X!OI-kawufYmrH2hBcvcU}tXxNUJWfxqO4Ewu(Q^gEeCU@5t^Bq`RolpLB`p&8p$y zcU84WH;`3F2f{2H{r9s;hg>>1vtlHgZy@d^DYsv&*UB_j5$N20Cub80`DX50Q|2e@ z#9T!pd%I}*@`sj*VA}#Wwrgu)T`5O0JRAF)4#@@NO^5t69kLihmi6=*{!RmZF;{@Y zpB&H2?-UC)EXioGObea(@-(plfQU1OY=7m@3>54VHe(#%A(uQKB|m(QMn8LD%>H+TXGI!+-97UH#*~@gH9O^}q2SSpC*N z_4`);$}c8ZzWS$DzxwC@o2y^*?f-uDPrm$#)%u5i)#~5>b$?~`D}VbhSpC{x@Ml)1 z-}85_zVk7M%^|yWaKUaVD&wgk1oBpf+eDx#OpS${Vzu_0He$Q|C zvDN?hOFv!x8~49>^&>z3m#i+ori-ZxuveJFVw%90PXtoDn#H##HwxN7k5;`UfB+P!^w` zGUp{k18TL#5gezouoxLed@{8 zY;sKmtUGs&zZyl6gMSL6Ihuf(>0e4Z&Ktek>~mmS59`VlA>T zQ&f!Jl4q{jqksY4_0zZPg%qf@!Bj2eXx?l5@)0|kl%6)L8Y30ZJ~;{8j*p>+`d)r> zu`hO!Ikh%aEqG?euZ=~r(oC4geCT|hV}FTd%P(2kvoVf4@J#Rup!a0|6bN(!ESyeX zx96HSyOL`~^K)a2c2mQbqIbJp4)_$;b^WDUJfH2*(RVuNC9GrB>R;g14W}ohazrE+@R zheleQ|1Mx7*0YuWVqa~UKQj$)AF-CPkM`e_dAX4nu`Kbk{@WzpnVgH{*WzpI z4!V~ML5%6vm^M$B_sq!LH+pYRftNsixGVd%1Hihy)CJ_9W24PoW6($)O7TSD?|r#Z z8q0=*;?&D_h_XrTg~hiv&aVXKOYLM0BzKBDZEtNGBQoN>J-Y;zbOf+(0*MZJewqH~ zqc;h)t+NY|b%Q-EU*x)qJ>+$)xq&0wxHJgfI9aEA_iYrL;X5F&d9zt+yxx zC}RMKIQ)*_G#=@-!kx1&b(Owo!=-3X9>oIhq=1Q)4gBR3dE!zK^IloaSoSv^!sq!- zhx{}hGK=YR{53k`bA0coeECpU_h;eSWAreNkmAiDhB)EJf6YKrM&sqIr zzx&5l|JOh9AFqDL-}mcRzwMX&?W_O#zxZEP|Ls@)= zJ<^2sF8>>VDxbdtMbasGk~b3wfx8TM10?)($!z6*<-1CO#>|{CA%VgJGe;mgGgdNa zQVh&EHO`Bme!@&VNDX3Olnv5`{Ei5r%;yQFt)P}_#jc%5bDU1_WUlm~OD$1tbO9j1 zk+&evVY^E-m!>wL_AZ8lIWq6NxVU8+0C2r?E>>-x`(Knc0^~~=V?f2`ltA$EJxagj z9|aBso%PKoP-P7jOM6vlz4^J=X!WGE+qmVe7*@+;#-*uX3O26YO>*l7(AN5GV;(K> zkj>lV5gF;6F@9R_0aR#w=4+WS-o!++e$5+Wwy^)n4C^W8*xVnGIA;QG4__VQ=FCmL zu3llIJ;qMp*=#`JKFTi++fM#q)$P}o9H z|F?<`xxa7TC^^Ipy|*@sWz3}?OTL+6r_4KHE$yf=ga$xdzkD<*C*g)XKa(HZ>d&Yj zc_!~S$u)$^N=b)RzO54#49{r;H}08Ua~xqR9mmQ?cR zC^k;%1T0-g?vTQ|`zEV%0#=QHxR>A21^Pm6ER-1qN53GLj@A=18|L*sG_v&~56My^a5B?kf_3Ar+R;{?d^4C`X zCqeU5yQkG>H~-J-fB38a@9O_{=VzN&@6JC0Y(2+EtiDMAjrRGbYEH^jy!-Aiul{$R z|NejO53T;?uTxwq(|`AW`75jMv3fsCV3PA2psn34rhxUsrN!9s4YFV1$lPOW*#NJ_}U!Jw&hKmy-HPDz9 zbLkaQc&>M>NG))c%j!AChn6k)z66N2mx`@*=plq!|1?B*#x5{`-wr>WCCstoEL#EOlCob=C&nmclD=zW|qgZ@t@b{udX2~{< z`Rs1vhO^C?^**&Uy+9zhK2KJKy<>Eyz;sNd``-X)g{a)*ip^kXz54S37{7_NuFn}r z8zB<0>{s(|w)1K|ycz+$^RW0aLE0VIFK#X7w=y-e&ocLUEPipb)s-8sNpb-oZVl`L zfUZg=?<8SV)3Rec0n^La%nSv9bV6dhQR}$AZ5y|;yo=Rs+}mS1rXCk3j#52Ib9N(_D{2Ny_LpN57Q2i~VLrS{axBH8}o4l?` zLNiXY^HKnpCy5SOTenX_6>i1X>NT;k3|0nOpuaVI%ji5x09uPB-cSJT>D?Tteq)JS z?M{;3sNWM~Z#v{nhx~dS^1anBnnz#!Fw4H2BMY+3)h%ssQ3EWO-o(yjigE{-vXd?N z@oB|uJS5#?vI=^qDBp`;IbeQhRg0gHNl}xS)o_Zvxv~b!WIST7s>c^?Uv{C;!f$T7B&sF+G25^^gCle{}Vi z{`tRU_49xHkFS3IkNyX%f9mgEt$yF1`Ae%m_wW597U^~MzpZ}n>ROj&?{ZIBaGGAAcgLEW zcw#RI(|||ysTM^}ND|Oj%*(DI?yOkfw{2G$!EIb#Qo>mHgu_X|am>#-z&!pADsGf& zE)jyeT_Lby+hSY@%Piv*;}x^9)b|6hfv2{)YA1|4dwL$d&w+w#w~xei7Wim+z_R$F zt37;oeqLO|uBCipzn;C|9`I;)j4g#dbq77S7|NagIr~1hcpyI4?-}cKz_Jzx_3pD6 zl111Biemlrl0TG8j3A}d9-N!vy11Z+q0=8JO^x?HWpQd(TQpGM6E}!aoD56gqL{>D z>L%{aT#xkMeLN-C&K$m#&RPVakBm&$)HD z!+PejjLEImVtad@^uayfapnS58 z^;GOwF82&8T8=KKy!B~HDmT_P0Ot3`rc(py73%)T94>BMtSC@jrgi(3HYYkcrZm^^ z76=G1=YkHT1Y!>Q(@i|z@lKzUDKExv2iWH1KiQEYvNYMUjJ8P8YTX&<60rtAd)+eD zw_n9b`KdR_P2ACWxqR18*1!bCW-N4uuBs3Gd3l`+1OB*nn;(^l$&ky?fEY2Luj|a+ zXG=WyXb;$hzt!(v=+vIPTLxM&a_yGUobdc&20JQWl4V%p$`q@%uGUe!@58_B!xNws0fBJ=zyQ^*)!q{=`7Sxh~IG&uC@X*>5_)JMulu z_*+be>;ZfBs`<`ZdzTzc<~0WyRdYlrEN=39Yqxp4OaG8*73LYn*=la?RM+s?`na*D z`ZL4uU=7DPx9#O2#*ZF+(;;s<dr*#U!F;rf*yUH$o={wG)e(7*UItH1y9->v?wfBz4!{-eM4cdV}8xLf_N zf98*@{?N`3tM(pOoSHU;bCCf8{5B1`GJFuKws>{R^wV^Dq9#tKa|r zFR%W@pZ#xEtN-bnt3UbQ{)4MO@q7N})ldJa|8(^SfASBke&6r-lP>`m)nN8p7f zr5N;8peZn@M<$`C*eCzxreET}nsN1X$_BeZ>3!hByAk+ZQ2ha`7aQ9y9UW7y!M_(< zb9qod`4iiUdjkBj z%W5o=*^9xd zDY`48@3)c;spjO498Q*%0=6Nqj$&jpRG#(wfiZh6liS?da`#^VwIzJWdh>3JT;uc( z6aw9cwyCI ztKa_Hzp?tcfAe2!D@fqMg0RwKR}>zjn<>}Xt>L=*AgH=*y>)C%ik`5%v;~e#$ur@8 z5SJ5pak0toa<|B6u2^p|HGzy&S5$Vl&z01Es1xx+sPuE7;L-hWfX35ze{uB-Cw26H z{Kq^EW8mIrflZeW-(G#&4h8StQJ&a=TO}uQfqv_o7`WY6RzLn#pd$2A{0Sgbe9KEU z#)h%jtiJtiwb;ID!*Sr{s@?CoxZ12fFp_&=3hf3u{5OHrc+F_LH7)nIzNRw3L-FRV2$6z=j0B`S`O^z zQcbx9U@5mr&gdo`#%ROc^WwbOZ`9{0^N$tz*MSFJ-?mk;YJskg211Hlv>S$0Saa;3 zd!&f&VudNjSlH_+khDB2K)fwZhJqXr954nvQvV(8p-VG+xr~*7o3{7wpkW^YW*661 zCu!|nCefohV%V9A%r0? z0id|inP&mSao-8%4(P@ZztA=@ty8D17JK*BS`1$aOG_D^*eA-V=9@clTx;uV8QK(J zebd-ECcy$wG~TV7O6Z)eom}W8LA2@oQUepCBu*_bv;|_f`64`{ZPiMYSX}$fwVwL1 z|9uVs<_e3+{dkmUGT;X)Zt8U`C4bB_>v}S~o&G`=l?am&7=X!`Drx6J@t&>ATi`yK z)Ugptk!y}7HkW#qQOE_}a-C-cfIhZ?xk3ii)cSNiC2Tt1saOv|U*0OiP&U?q0!zI8!kd}n(&=@a$Nw#FPjgjMC=Efz%ZrZq< zTcPoeb>NmewQz%(?-7^%SF8gn%Zz;%Urv<|PBzsfruGBlcHzeRM2jWz5hl04V1X6eWM zu0QIKsl}?_LG53sLl&U_EKJ}|ES`>V=?~K(g~NDJGOw)+-*kwz`KCjDs1EtXU;L%j zSH2=)jWFrY&;8ubnKwUp^m#|2YCrq4KRZ9aO5^$YZ|JX-P7DiA2q8o8Qz-pTdRpxi zvISB`R(plELqROpy5tLB;xTI-+gI$y71Pjum<8|$EbiQ6g0mBBWpA-Wt4v?oeQv`u zOFm_i(A?NdbxkQ%OUb5JqpU9WWBr}1`T)|JU>}eJeeJ&Tjv9VJ{ zN6PUG+zuFJ)tB#C_F6&aD?l#SMX^YMwF~B|V;4{chPT`>#kNfn2G@778!2H#9``rF zo6D`fC(vKK-&ud%3W867w7W<0Ka(+rY9}`5&Ng6c{kQqdMG0CgSNouL+Lk4`ckk;5 z<5-CXY-3E-3k6UX;^mPr0%C`m?1B_8_T>olWUXI-tR3*SYfb>IfrAw69#{%A-d8#y zz~f#Yp1-LVN)*ut-8-fLXc**Y1O^P}>gMiw@0y3=cRVY=H`JD=PhnAtVQan|jK7Y2 z)q9kyv1|8;f|eKH8=KXfj1lu07OwhixmReVY2#Snlwi!(s?r-1yx-3qMXV+4m!mkN zi5-gVDKpjaBz`E6l2UCB^(S^V<)!iFX&@Td1n!N1R#19@E7!yv-2z1~&_mgGFYdn> zJHmerdMdD9`L$q&~dvrs4R(BuEI%KUGJsiun3z z&&tfTG(pw3{hJ!|uk&|YsAWXM6|V6a!T*t!3$!n;xNm3=02>4no3qu)#R64QqCO}% zyW?7HC8csNi}KeFY!P5LjIX!3Qao*SmFqCaa69dCWG&2=c6795QS)RHSZ0i9>QVSM zb;Amk&=WgQOiSXnewsfiCgbMg+hrdE>|pc#}afJ?*KU zr^Sonr!1$4v^K^ym34b@ZR|$~AXiSHv{r9?R@lKIH`_8rfNQ|tI8__+Xg=0UFBuUT zF$7;UzP_3~mcDnwhmN{ZQ=JCot-2Gk~S;Z=&s(w5_Zck>M}XjhA^ zn8+0GsXAwk#{gsRq`zm~GMdgGjGs)%B7`=!)T_PQj33u-FvLge+Qg^ew9UKEUbSj> z#nhcKJz~tQ{bhazgkv?&kBkm$F~^KYS(nC-ex2_x`bVy) zanlIK)>e|tAhY_$n!Q>>u`0ttV!+#9c{z$K)R0*9*9F+_2*KM);CMaj<3HP6(8c^s zxWST)G2fXl{HbH;1;AqDOByO`xVAMs=Z%Ci=f%1Qr@#~TmbXBK7)tb}JQ!*uErj@Rl4BW)mJz)6#qZlrrvII4Sql}kx zfaa1UDnzWywXv(og~ANXece63Pn%t<6#%aOX865#YPB~z0>Zh>>(4;?tVC^Ez3;P( zTl3xgOAcq~l+01grYEe9zHe?P2X=N~`F?Vb&x&PBM!e~eHy!e(Lw=nOVL*J!k*51n zkG7JzO>hx>v(Y^k;)C)Jdq9UgArA;xz^+2A&$pC@MZSr(0+Nnmajt~>eq4}*5QP)a z=y>|D>~&fY_swlE1tbEnD$+}eVk*)ibVeGN$aqgtR3&}39U^RJFGgT$*|fcTI$t{q ziVl<|aN3~zMOlt4@BrL{VCbwa(rgs&BMa^(HiPC{r#Rf^HfD-|%Z?V1fu#~-qcVI- z+S|HUa+EbqSe`s4XaH1~dvB z4&Y5)K3_c9k}2k?cfTQ&_mpYOL2OkFRFTKUFKukiQ{R?ga0Z;OF^?TUYdx|7V9VfJ zQ=IkH+I*>Ee*Sl`eSk%87tLH>6nNi4A8`B%J^~Se;58O!3iigp_K4iADSFg&oYTGb z1{!+#Hipl|-*Es~y`UcCdTsOgIg0sO`ew8F&H(ZmJkN^pYtPl2T)X;bV&mo-BMS%y zdMi1xs8+xh_$X|kcDD7`0k{IavZ2#S@rRnvr{-c#?G4-H5w-a@}@(6O^3{)_=LZb=wHf_ z(x-~Y?UtaqP(}s(=k~cx`L>n`vKYHE;O$&ZyePXH3S`GppBSX-jCs#85fe;z&{bJdn}j}r z)$yz%`2|3_h+TS!1;8ehIYq_Jf3w}wyI2shEwL(}f5-l;^?{(<>Tmfx$P_De#wu0~ zziym^j>y%WP_59WU&Y4&(Og!Qt;j9604d5lc4ee6{)h6o1(@&U6%5tRMg_E>Fa)RszHZrRwrT-F;3H4ZO!_Zkym+{y;sa{Ef@ zH73rbP>v}_%tK{Ea(Uhwm#b^mlz5rKLGnlL#*TVO^Rytvj%f(MxZm0QES@cR*!(b) z{O-Q5il|EUzS0lhoVnJ$4t5sFnAnKl%9S4bvD7FFYz8>EtMtjycwUVi5BB$uk_3u> zY+I%QXnhkSld>Fts5r-fjlP{DATR*cJejyi_s5o0b_TNc{+L!L4rAkea#2s*oiW{J zgxN|gFnRc`^KtN_^b7*D!`+Rx8Z?0Ijt<#aWi-_VGKbQ?a!I!`9|!yE(K)-RfCi zDs!<~`}%sbO2A|& zCJ)@Fc$k+D)~G(3ctQr^)QZcU?e4|H#po6vScpVDUSH2@HJ%Y?vln;IGzZ(lY^8Yg zlsU?sy88B^<|_~gRi6ZWhvZbh%tUHx6U_bn^zTOnQh84sPw^YG9s~RekXDE z!0!^DM`rl`O^3YckT)IjgF0kFgJz|DvA>eGU&=8-w6B8hg5e0jBy@5eZh!%+)+dA{ zz*5lfvONo7lH!sfnFlk5W~ueVomR2kq=0*7VGr-;+^K+0D0F=rIbSHz;|DO}L43%t z9N0HXGv!leUv4%huI|Nwja!S1Nr;rlumrqQ)Y?>G<@Re$ktF<1DV{7-PZ~u@2yO_j z6xb71;0CL<3)ygS(bbdbHpPJn$E6M&v0UsJp;(CvT8OoZ-KZZtE7$E=mhFln&7E{} z``f%{>{h@q*IWRGLaPNzBv4=T+Y%h@!_;T@O&L0BN^X;4g~~fPQ;Zc}NLZdLO_L(f zC-*~t#3A$?f;+b^Wf^alAYR8lQb_b(57svS8o%~-9k)8LN?N;K45a6z?5j`LmPBp< zIB0RDRe<0W_a!F7c`3+P#lVuZSc>?=>a&Nh0S*{AZm9mvwZ6q*=w{8T{EGR5J&mC$ z%X4Xy_f1PF^U<5n{lv^^?7YLmLK#!Pvzw`ZQL_Km*590J=c)=9sIlQwSI6^Ng6(+M+`!zwfvPFu_zDj=%xX zkQX>R1$v*dG8*WY43)(Iy2gT(Ppmpk(SKso5s zlVqFk2gx&*)(W$}D?PJAw-;OWD6Z`WP~2QZl``0hacf;QXUlpoVPRXJ0Z3P@+vDf9 zu)6cz>k*h9!DO-Yj=|HNXT<;&77zfQJyl~f$%M94+quuMxLE&oQ7CpbfKt%==Gnf` z;=PLVs@E29tm`Bm?ChOdoNw}^{+&H%t^32_tF=}eC0GSwl3R{Och{Ct=DlU>nM)~* zz--69wbcAic93&xwf!=NX76g_v6Z}ZH5M6wrU0xM_-Xq+t~l2Zz)d!pOXosBBzrU= z3RP&!zm8(Ry8T71zYXJZDRi8BJ7!g~lzF<(;B!)PLyUlDYD*JaMS>5&=e_-|n_cbw zeGwy={9s0@nJq*kMwPL25UTM+X2sZlcx>A-^H3{ti?=Fv&z zdT-`EOJ4HgWypG7Nkf&wDbBM!dv6(9x%~TNG1ST7T*z-aWMt->4tdidt=dmHk{n;& zLD?lFs^p!JY&(@TL3fk&Oz9`!CJ>&;S*!Y;5>FX!CWV}GB9zM33MjTe?HPF4=Kge# zGEozffuq>HfZK^uuN20e-6j$aF>&p`nL=pmr&H27Wt@l`mVmQC8)){48{0e)aDWEq z?DWB%pT9@oJP@`O{JjMP-nY$}OV(u`ve-LwfA;-*zdQd-`QIu3P|1-tk`FB1#Y_e? zlWCM$uFDc6s`8O)Z6}JDfHUD41k+)JAb>&F{W2L0&Ml&+2-PFHQg!#OO1~3?T)!G z*Pi{NA15X+3m$k$$c_ZYUhDw8V#X54kG&V**?T2)JDxx1g0bD!r2Ye6v!`$871KD( z*HVwHdB8g}Kqx`K1#~Wye&f)l^A&E6bqi`rGEnrE4vzuG10hTje4KG{wUt7EXek0-Ev<} z%{s{P>7q=K8E_+3v`O|XjSg0n@tj-w~=NL}_DYc>2B?$(?LD3+8nNkrOKuTFU#YdQcQ$Q$=###Kg) zdA~NtpT%;P_|iI=*%}M&+7c_`>nbc=|Gd~qWT%+<$g#Sp`_4ZKsAIWqT(>KZE&=FW z4JD{93)&COgM$Ct3$=pj^+Ykmrh zOr3>Wlu^6&=~lWV1?lca8l*d92#4AVnxUmja%d0dz0Uhx-~aIJ z=f2n8YyFnVp&^)edk<-7j&GrNcisT0=9(}C z>T|_ftV`Ow3d%gYeAd}JL3b`$S$HkDLc2q{C}a`6n)2nel}B(AK2h|HRX06BQ+sEd zl_dXkc@&8b&!xcAf>i_7_hm`44j6@E!@$^jCDNjnBG|9?yqEQF$w;C!6F0?X^v9#*zwLIo z#9`#bs$;ZIr<^RP7#0|h9YGD!Ee;echp(9Vi-hQ^YJUB5qHvK(e3|*kSMT9G)Y*UP zX-2m>@3UBE@8mMui7Vz)p1%)SzM>U$T~f3I!Q=v{%8{msIy33)YOHT6qc3tJZn zHc_!#Fg>fj-!Z%T0HZgAZh|k`0JT+joY7O6 zUzBxpcd%zat${T%7r}tjmbKwXIXv-==Go9)6RL zHkQS6edM-y%oxN-T*GjUfle*_ea40i?CeQX9VGN5 zXf#wC@VdhbEha}ia|EYyjv{syZ!u`3J8g2V1U?Ut&$ z>@Geca4MyCP_3?AfFDs5ATJ`F4((oU$0*J{&Nbl7u>ktOYCYGFjG2?qg3^wz505Xk z#n_uUHLwjaTHm9IQf0J;)b!6G(|WYkq-nhE$D8Y=LZcG{%Nh3O;Ra=AB)tD66`1_~ z7#aIECExZ{+%-?4UV@1R#yDheTnb4J)Q{iPhD8iX36oNyS>$NJwo#K`Z%}oe&Rc(> z8zGnL5ExLFWeKLK3%T4n#)0rsr+N{Iu=}viwn>W-_gP^G@`WOPe9h+Lx%Q#zo+&Qi$Xho7ovH)FQ_u9~)D*eNl85wj5 z2&~J+S#pGI!@-Vhb`qYB8w#{99Sz-1sZcXdz@70l((FDE2St3ftx=#-> zM%=nL!p1!xCLY0EHl2+)GSdy?+saeTwj+C?JXS0{zdp{kTH)k3@_d#m$&ydDjYMX8 zI>KbHOKSOz`=qUVdK!J)b9-ShH$}cpEAJ@z-nWJ)^;KCpDX`9}JxXSJn1flBNV%zr~&vM>2arg)OW+dqpF#l2?NY+@g`(L$4 z<}u0|%kjMAn#SS3g57JXWX+n&s{bj>EssxBjk*g|?m9uZsYCsgIZ@tT#w}@fvBRJ$ zk8ypJCda#}X}R>B7+K2SY*&HLUe!-u7rd2ytM*Z?h9%X>P;d%2N!D1@Wc3hwrvz-} z&rK41(pN>wkg&n^K6m+5*b5OG4rm2golX3#VeZ$UzGv%y@_txsRQV7s=4DCKzFgt( zlpKzN)@|gm48T8e{&cgWs3|-=r{lSEqcH07ZG%p`6Z;#8L9j|z4?#{g4N(F8^z}kt z;>&4dIPwM79arSp;VjBE`-hOOGU|w7+?mg7Y#Nqj#|b5@ z`mbC#4M6!x#;GqAcF*L)0>JlL3c(~%Na=qag;`+w)LogbRuBUvB6zoh%HviY-i+xo zf)4q|xGjcu`LiKQAQ`VJ8JWs@%fF65z74QA82l4tA{yh9@I z%-~4j0k#%j%dPTm6&j+VfV)?+Fk$|Tzl>1$W`g&M3lJi$^AV>ecWL&5u>93!{VMrj zY>+__ya8P{74!ror!^+T+9vrd^E&Bh96_5ohRqft(to!6DR^YYxng8|AwuhBHfWmM z-C;1}jXK-WM8-=UnDQ`~=Xp<8xY8M35Sl zKUmDad)6zxNafnVp-Jn{PYV}ZX+FOD!kC)2^sWlNR#d54_;qN#gs|QY9jsMHs5zCW zu6rVwra_bHWZNi<_`D%c=Dk^e%?D_15uYQCD3l|=%Tpj6emxz0yXtpb6@#T^8@I#T zb`cYB{s0|al)DH*%15S{6o#C$WK_T$Z23)q-)kWsT_yNvzkpp)3?y1|2v>=h)53=W zRL1e|ZdR_HZXgS_WFnWrOL&^~+8pWgSWPdTpa;=jhui)7J)`NL6izZ@@C(j{c&^zK z);>eOh`6zm^lk*x#u+imLLh<+B;M9!zbL9GObPwv^ z4SktV)a^R|#_R|7uMH|1cKUr$Bio3L2sX-Jn;ox0UK7P4l{t$(Th6}q09SaS-QObI zI-#r+IV-i^Lcxz14jaun#e5k)nJ!Bo9BO+0`;MU=F^TZ>z1O&9hXL>)&2D2?P4tg# zX}RV_5a0JwlESPZageHB4;4d=!kry;AQvd?R_%!1S$*D`H_k@3=86zAO%fca)}LD9 zO^?$GibN~UX-~u#AP_wuKL%S3xBdCrsd4!dDim$BihoMDUPGtk?6rel?zU0FDkC3S zc12Fwe6cECSq#rQ@=kA!i%sTZkh>F#I%1N+6BS~OQlT|wV-_41iuoO!g-%*U+M0Hi z=vos3!%nUodcCvO)w$FVo7e);SGtb`XvXil-?Za=vk@ejVb%)14uh@iaH&s!@#*>? znN-s7OXRt3!9k;n63Uo`F{?%$m;EPGK{^Y{_DHvaA@y(CluWP)XwYw(fG}h<^Byek zc}GQ{Q9aL(Z|3wU)i6;r1!iMEo!tw)*oCn1Q!bGRz=hmuJ_#+~G+bvzmE3Zj8Iyk} z)8b6`bh2uZW^Bufq(l~GE|t7$tw^;*6q6?hic=B4p+Q5ZZLmuL`__TZY}Yg>JszMH z`?P00t#K><2t&E8!=wg*67M{Mz3U z6UzuDCANrh#UEKr^#P$EEe5MTn`U$`I4aFju6jfL3x!bc?VD+dmlkBiKRmIqbt0BR z>)B^54>Vi#`rbr;ZQydW6(l#=_>v`J^ZXO_@}Kpy9I~IhYRqz-{q89b4&*% z$8*@r+dF{hvY3WeNIHIQJ#$0S#?%LDODwAT@k8|Lzrh|r$;$YH_S)ivS?d}_x2Vmumo zRLaQlV>m5@}s8dxfc9jXGDc+62e%R7*)YpB*2RLm~-{BGv)lCK4qhydM;T*0$ zfl@2tTXm;HT~inB*0O$f7sL$0?k~CCD}EugWNQvYP8-+|4}YQ}l}M^z5Fz^aQzP!n z#d@?_v`4n`bLJ6cL)Jtb!2}6=rv{wZqu89t`~vy8K2P#uOkHBkl{k5{#Ov4ez(Z{zE@ns3fhc+#83PDQKq8T(dJ)A}uGten4t8^Ft)vmg8uO+`uGArXCV`kxsxWM@L-? zPnS0Q;j~?A5lW@BPqm%mM@P*`WE&bqmLSD8k&yX;i;sw}ukFrgoOL^Qjn&JQ+CG>T zz13VCZ}Nyif)(DskhL)Z8|f0St|SO9Hf}5z31fn}R{X2eq9-q=`t?Nn7+y+r;c;f% zT_zj7-PeH@$$2eTByYS-DMjaA#Hi5pkaXLBCGHaZ0)B+8=LSoygiE;yqYk9%v15uP z7coY`LJ3--!#Cfr<$aEhcif5i)M`w{0|}^)Kp;0}MY1Ose38hU#x`hhmtquP)oFpJ zO#9srVrmR+-SA@8!9IuccKyg4VVA+J+tSB+F)_cx{b6xX#15QND;y`|)jM7Hs~g+3 zW`y~Qm$)zezXY`4OE{~%+rz+eR{N$pgnCMnT z%^C(0*{+;bq)XLOaCL?}yj&D9k9Vf&9k|zvt1bBN^5NqnjRDP|DZEjI70-Ov#8Y>@ z|MJ+eG?)m1l$d=ped-wZDq6D{+PhKn=t4neR{%&ph%topHU2qU*;8as=0@^}KPT4=MDvO{CgzxKga!b8uRoRy_tmvcXcbhX2i+uTZ zzG|P_EVGK>3zY}gUv|XLGSAl^Pim|vxJ~JQQ&kyjDxI*=THD^}j5Ivhh$W+FHBOFF zABa9x_nagp-RWVJI&3j7XzR|%3yD`I^ZZpi2weiWmL$~Hl2ZwfX?zn&r@$#pl7TX$R*gM$d z+P*>Qat2yy?p?@)fSqys01_1z57EjvPO2>r99M z1rYe3s_?}356!zu$XIvig)(%J z0uBf|@i|4|$+$$$iq%0?+|?)&8qVl{wAi&Bvqhv{Gk`1)1z781vd{2{zc(5!)@qq* zss|+0Lr$rYkVmiRlpA5!AmvHakFT$TFsQt9tDD;voi_)PF0&t!7U8kh1}z#>zFwLW zm-*2mOTSX#kEq0sb4aDd_P(+BJQbJNu)dHnQt@WAUdEQIsk8!S!eMl>G&=>d(wZ2J z1ubUi75;<_r<1rpsuD5g_5r{MHCDF*iBFhLBC2YAegHvESA*MN-gZ-HJPt40g=c2|U(L z^^Fi>C1BP6K5#JOza8&#;sRQHNIlY{Q4akq*C^Ft49F`HV02%qZV*OY`87;I^yJ-t z2rz?x%U}^!QNZ-ack16;oGajAWJ%#TF;-2^t0`n^!+|E|(%1YZ3}*H1!+Q@l5F7JoJyIk=8v^d(@Dx;hQm% z=^RXh_|3{ul#9r*L6S~!vcMX)r#ne(>fv`EE|gy*8JWH)#Apb25Q*S`8oXTI=ltX< zx6v}J9dgV;Fm$OgndCPj8qbVs>bZOnhrC0|u*qxa5lRFalUKQTF+18{fnVJp{1gVq zvacpviikpaWXQuhuH^MB?Oo(x1Ud1Gv-!%&un-b_B+exw<8r-*rA$Q z{^Wga3&~VOXVSp?DV`n?G7inQ3Vs={XCbLgbpRfsPYEzzDg)!#-BnZ60oZ7B~aE;?#ll|75 z@*?#3OC4FD(q7=u?&$vID(pGN!~B!>2a8sE+7pBlQf(!y%HIJda|=y@Rpqz+0GqVI zo(qNAy!J zF@!Fu+mE|I5ES4r(Z?50MO8%tH;GQ_gWCzn%e&?*=X7SfONTf4IW$?nUvbjrgLX3* z+iK!XN%{F1!Ar2>N$ap$&HyCt zDo%X$m(2%+HZNyqWYrpdB&slx@RVW>R6PEytFlT?mox)u8JeR_kS85FFJ^U}KxSMX zbZ~RWqiT&#xmJ{wy{zZ|-E0+UZE-DodQ=)}UZO!nOPzS`Ri3FHApzQueLoE9>AOU@8lQZk_$$qU^7D~XPd=ozt|6* z+4-TX`M+~NX{n)N zkz7tSpFW&(5i0=^_d@V0ixp!x(I2Oix^$mm?GJmnqf!*#()vR6s1Mb?-|w6+dPxk7 zz}=;X62mSisd57so)n_2+hY1$&-;QSUNdGF*%=q#OeV3KeFTSh&=#cvn~N0S<$MiI z>qLmrSS>bzYrw+7uyt)Ps7cN#1lH%%f8sZ3FJZ|YYNu5Tksy)KL~*;P6>x}|h{HQ# zz@|K0yeGEf_w##SBt5H@Yqa)bT>z!yjbVBT8vC5CMR6uEQ+i8G?WN&A-hE%0!*mA- zwgQix9*~*61LVQ!b9z4xt;gE+9epc&N0w*kW(|ibDul&J6!yqt$>l#qz?$Qg*Mi(f zoUo}%f4dv~Fq$)u34NYeI>V~A2-tT3_k1pYgTHr5fl=Sf^Z-5pnZ)<~{s!Ed^gr`L zjh`OwN+vwoUXjt;+UUEQWOin=Y-U59AdfBSB?z;tnN_ELvcCbbrM*5e zgf{T~tt3dWu_T$=hbB(tFL~aGf5{5F#nI1P{|L+lFJwjgc4+Ez%cnV+ z!=)_gzVlA0g}$^o#w!YU(QRXxd@fu$ERI2L_g%e_l)|LrZc7bSY;OuDc&&+KdCKUN zWKiWg4Y(p~kOzQU&44@iCPuTB%HmtYlEp9L5}x3$E%$YS46k)31hiCPAaw$6rTFsM zOixCFMPP12ZvOGb+vYtwxGp=Z0xz=Zu{xAdL{yn;MF@1IiGtO@2BP zqgyCK?|R&)$@fw5K_6?-ZzV{0iPaw*`A(4PBY`&(xs8uI@&tm zzJA}3%%dwTz=?i?GV`HRgj$05*J~b|X<4eq;U+31r*tz9zDOjJ{~$7DGUQm;wD=eX z4_%pN5)dX%$O0*07_0@?CZP^7tK{%e!vF){FW)EUx#nSuAQ!(gMKTS+SBT_p*-t6-m6LJw;t*o8Ds@4^kNKx*+q6O`XrW&gkb#&5 zEqe5gCyj)yn5uo)#b~)ZM~Pd5ils7xKWx9;ZU>)pQ+-&Agg0``_B*zwNI6vpn3xIW zPl$FzF1+v3Tn*{7%{Rj6fs`yD&4(VN-}UImw|?*gtIE^bGn)#&q-Y{fBg$zZ$mgM; z03RH?X=w<4(=DoP4hA45@{i-GU^bM;YE1g(H2l(cf7hoE9Ujaf+A;koaq~xJ1dk@&Gb+>`OsLiwo{8R zttExFwbIO%*J3DY^Y$oPZ(d$=S?*~p;@rGsLnj49#AM*)x|LZz%Ue-Bzza34)!#Xlf067OSj#SbM$FLi95*X%)}+()J;}ZP-;~v8)_a?j z`|II&*;W6`lfd7E7H__sld9$H@vqHvbD6T)%RQPTCygkeRXJzeWh>Kd^RJ>vWGDZZUj0oxvhfD2r^>Vl#lXs_paG5J}+ zv^pf|beE|~$~jJnrr^N9g1@KTOY(TQ&Lb~Pug$2h;Xtppz#BB4asTBsDn{&*9v&Q; z=N1isZ@&%kLs7@XI)^K{4jgOE5@RqDap77uo}9?M5_0{AG=tztcpVduK6Hg@`y+@k z?Yrs00gld$T~kCKsOEF3q+JA|@24H%zbJ7ETf38P6yln8{X$(dM_J)=qq&=+o(q za{B5MK{}QyltJl^|9E??p&4MvzoAN=|krWD=yIKAdI`vNwf*>HtvEY z$S&VM<&jI!)heOG(BOdd^Ki~ri&dugCt}X7jQhW4|2&^&;nAJ@FXfh{vCz*|fToHp zkma#{`(7CpAgY7~yN=;n{AAu0JxJ>}*a;t16?jMOf*4hWna+VCWw()OBNai@JVQO1 zzCX???m-cJ`En*lihF%6zAM{FtWKEUx`_DaymO)K%#Z?Y4(B(x`bk{?f3 zCKXP82IOVt;mOpFal_P%7h==W9tS&AjS)O#DqLVAFu!0Qqt9dEacB17dK`@;n?lD+ zdZ2~HNYb>L8(@mr&?-}5%t4~Mgu_dLT1=2#dvRQtdgyNw&Dfu)ok8e=Y`Y(qdthw3 z!IQ>dyX#%eAYlX#Qh2ZPr34F87}3FEh)XZt3@OnQd|Pe_Bv1SquXGlx{Xmnlt-8Wg z`8t7tj2rmh8Th$e+Oj`j;C~0;$qMX3`_O88B=DUIRf-l?(tX zoeKyEPrq^O;dUI|x5o0LYmATCl2(_g)v>kBC7z9_gsp@f8T3>)S&#HPRiqZqRe&xV z{~W#gxDwt1$<7Z#Br*ry_p>~_3*T{G%X`J$iJO;*zzREF zG(2F?T=~=>L$VeI>x>^%3d6yp(GrhHf%Xy&eqp%kP9S_gpuw=7gTm~&XxUCV;oy41 z9HeijhII`Z(}0IB0hx1Z`YU~I!+r#}j>H-5P^oZ3KtO*eKX~_D(eAGvgP;#uOG|sk zo|rY|IOG7@AT4@$(8P^PVWB~U+GJjaz^GrcmYm}v0?rh!4AIFpYS4hdc@ZA1rIt&a z_BpO3zU3x69K5hYUn^^gJdVXMdFy;XmVX0uy&lVEn<38ftOW-;sA+|9UTmt8KXJQC z{*We;NR6@59(s)V6*+qY|D$lTIb!uP>yGSTXKq@;aNCa#V@M*`DVqxanDQ4})1}W@ zB)nrnGlzuk^TLjzyPy3Q?nD!jyccpI|Jt2#O)pVj2Ne;^@XwD0$gx7l%rQL(?hmm|uATb|BM|n*U zFLw)3HC+*@G_M*tu^YWkqA@T~$M13pgH|*~5nN;7x7lK>8iG3HpL)6N+Mo71pt(0? z0fu^gj`=<2MMtg>jITb z@HOjot8>iAorzKCEI`YlN8cmf;`G#jlTM1$kM}*I{nY+3!9KFx{?3Bbg{$kvbcem= zP|SJ5Dpf9NE;vW}>y+R{!8-~_Po1T4?FC?TFx@NXbos{@haT3GpE;Fm%U4|bp*;Hv zc1pciBFB_UFt@jLa0YhNT&zJBqqwK`FC^TAqZIFq3m z4-3^<%S2LkWBdeqQa=MwSX+pJF%y&u8RpUFRfNR?CDf{PZ8+ftyf46DPXaYRN|b@h z5Iyw7R_?WE_%#$>g!duI^PK%Yr2wb+L(Ihov2D`!(W%GKl4y9}kIModS>Zm>5txn{ zWqZG4U02bV{Q*xC_|iM%w=iJk7ko#_r41^jRdjV(|HNxoj=k%K)k2^u z(U_TAbTJ}Pkx@1|i6~6;2Rb~Q$W8TDNM3ZbjAh7wfmFeLfT`|-Rgu(TcdSW8B0&Wj zw0bZpL0faA0oN;hI7#KpJd%4w-scXKcnS4|C%?Klm6t!yae$SDkDZh~=$wdu3G@sq zn%YjXX92TqBx#Y5B7$1|`6@4}1THr_q05+Wv6nvc|Jrg_1mAatz6<2-6Tx8Hn#WxO z>K>YHt=vzhhvvuXP#1Y+eEAhUW+f1t73icFhtYmag3)s!DD;tDwTFv(F&N@=mofZ2 zH;QUdI4F~WeWIS&kbahNvz06W|5IDmohpn+8GW$Gr(QQ=_IkRHFy+GUO^Xg2QVcV& zPdt?3AZ>DmGz$=U9v^)X7vg%tA;X}wnaX2Spn;h>#kK}d$Fi?d(wjE!B=L%2H2!}sMo~~ z4+)UPFya8)o`4CwUDx;32=AZ1nUdAz4&cnZ<1qVvq-55a_quc;iaJ$v-aNIe&3z#L z)kR`@PL1loSnS26y0a99i9n2?!TQZ50x3Pn&oZJr^j62-+peMXy`Ms0b#USGJ_an+ zT|EoCt)(Aeg|xCYld||}(S2JZWUaGKWYdqn4SInw$-WUTw~}sNj~tbp82L*SF>?t9 z#C*fbkg}2j0VkyC<$Z|)p8HcjG`z5$eJ|wAoUOzlwFLV%MPhukQ&S?`b%E%A*jVN= z|NepAz;`b1$h90e*4)CD*F`P|^xzy4-6uD9j^uhcWkgb4#(z{_L@)h;A9HF-{NxUP z)y=!P5!VZQ;6=$|w+tDs|9_8zZ;^}8$M3yFOfYofSFjQu!2+Hkz91^xpT6-rM*Egp zYm0G2I<+l|rXHsBcd}0*jTzj8jE@u_mmLW!s#)mx_cYPwF(9Qyn#=~f!&3ykze=8^ zwvF%$kzUu$eLZvkp)I#wuQpqKY&{I0!EPr+l{RJo%8eoOKz2f0n~*X+c@I#kT-V0~ zkv?dBEh>)=7@JB4mU?T2Gc5v|+etq!+16DMYQ6N3d{ngOSwV`H8hwX*ogzIi-OJIZ z3JtP2FCl0nIJFo_Vb(1_3t>(q+o-4nurA0g{7x@h)nQf40{+g+2g1<<3wth0w)UXoyMfs+Vi<-g@ zqVFc@*tVHZAUff#+YksRU!*0P_UiY{E|6j1si$S6#Xa(408Mz02;f`WNZ5M}ah)u- zzrF&;0&|q*lp`ZR2Q2CZ#&vz}$llvN|5kDPH!%g_W!9PZ2%>fUi$zEeepHMRdceye zZgQm)P6zPDJ5GgUxx7QH?OQ?T6wYo>KmXwLB6n0*N||QK3yZPxYw^5!YDjNWJQl3& zL!#7WiH1}jecry%W`<=4Dt>`n>_4u!Ayk1h%#1iZWsWw^d>t# zePvMwh`s&lld(d&b88vG_sw@PdF}6-qkxHr&IJXgcD0_1mfUi-EoQG0mjOuyrC;58 zOHcsJj0A{6pzEzTe;BVnW&2PAI^Xk(c4jo}%KW}xs65Fq9z;Hh6_v;hjN!hDqF{@w z_IN<}+x8kgaT2KH51p%{GHT}7X!~B$g+<&jLq5LYW$iOI}%xaKN@`0#g%@Oe$lB{RUV)hqOd0m^o3+y+!yPMc&W2A zigQGJP^91F?zRpMq_TQ0-0_%s#&7$_?M>A5C3KkQCp1kxEc&=szoN}peQq954j44#bvx-=Ti*8$ez7J@0b?A6;u>7qOxizl8dTegs8A%&B!yS!Yh0Wn9P~|7HJ46-P^r(IH^qX< zVdWTrYDr{&zgVQj+`k)e_QR*hrp%I>p;9h3gQ>;UXx&f_WL^_jhR%x!Y+%*1vV8}5 ziW5x_&Z=_wshJy@i&%@J=70f>=_e1p?XmYT4!qVdT&v{$00!ZGwL{!(ay(-x`cE_2 z&lCDnIXbayoZ5cyi;)%M-A5lzwa#T3O`)>dA(S&0z{=?j2Nm_SYK=vgJ?rDPooSRq z4c4ZmN=kz`fCv*rLM`}K&q~WBvhRI2cTD0%<%Hz2S`2_%)+dcFB)^d~Igvm4WfeEr z#^yk`@?Wcj>~J(T6MOtuVg^v;-XGO71jXh#sw{>W)^P7eB`)#?H^SVW+guLM{&IUo zC!XqMyDZ}L3!`i;l#7~I5qO0s|6kz34nL3!EpHvc@9{YN*gK;9YFHVu=)Yn?#~-m) z@enc$4{k0yBda5;Yd>4m#}`wzCGK{!u!-up6;>8^Ln6;^(!X3mmTCAe-BSsFPw|QN zZ2|oIvP<9Z&CE*ktS12vYf(6;IL%L^Eo6*nDr|8^mI|zy4I9AK+Wk8jVz^B`RySK8 ze8caTcBgl?6D|5ICK}-`E)gQbKin?(_vNh%R-A3>jJb5g%3R3uw>RO8Pwe;`t+tGU zlPPp7hw@3LV_U>8zSYWoaDXeqTzVN>bxt}zbv>C1z@)-*x-bWhxEn=t^mTv{RJbGNQqfPs*IbxbHnF7 zeX4ktkgZ)W5S?c$_tTcBe%SB{ig%uy7mGEepYedw6+U^=;I}|{`w$`QESQ6sj$Zxp z&M=+hJc>7L1B*hW6G?c@qeLt-sr%K7Jr&|Hc$J|>mmb@Yy=Lfd`o&p*Zo=sMm&1sC z+1n%TeT0c&9$f<8&1_+2?AnVv?t~;S!#-{`rG{UID+{Eo(a+^mSb6_R`)20u-(^&hEYOO6Gt%Klvjgi|@GxFY>ycqQ-??FB(l^StJ#`O-~oe zs?=KHKJ6Zs)J|Da45qp567OG&84vPt=%;I0J6BU_JU$(U;WJ$Fqyg&0tJuG0_#UW7 zUt_etHPKTV)X98WT6vLXT^pfolW*V&X$FMku22QnapOYNj!)bF-EEiPzbzw3En6U$sQ?^va9Q`DcMRSw z`M4DwF71BPsipu0&SGE^h1HEd>z+onnn zr4#e-88WU9jt2{bJ0P}P0vRN4Q>r5u#%9XDgRyKRraZV>wM+%_H@C$z z@IV7q*m?*9jX9~jVZuLMH`lPe_D#mPB);vgc?LA367H+af+xG+GB^^>yC3cSo&<<5 z_`;u8ehg;KokpSDqH+t-oWdP>~Df{b+}nnu*6O#2ZAJ$^cks$<(@`{Y7qn z{ikbDMoRlwIL0q=@6-)-ujD#S2;ez#Jy>#`jyYB3sy7Xtf;T@D0oWgNyjNE`st+=} zC^+aSbV5h?4uq#xX8{2;@EDBQ+`?|gbe5T)xlZ5$Li|-BHOj&yYAtM8b{qdBDJB;` zu?pDrI1^%XdWdRKTe-E&u}@S95c8CW@JsM+c_J6vNgEutaQ|hr7~v7+{Ck>l5>ZDA z1Ey|w2iHR?odlv6(o<}pT`CBD#v4nJ$3`PZ-hqJI0=_Av94_j9fAM__FY+T{KTa#a zqa&Gfaed;V-bQ*%si*wP`j~s*?~jj%|M8W+`MK$b7${6A+i8)Ek*M|NdG|j#w z)U)~E6IqV$Ag5r%c&GHOuskBL` z!c`Z|p+D)hLH)OUvwu;Ayi=ZRy)TU{LGK&Jny0~FOq09h4VJLim+yZ-ENphd9;(k`i=*74JrPMy&C>~YA?~;rG)X@(?4ivw;(JxA}C0D!xR=V3+a@L4sDDJ-mop6j_ zBMTm)BpE=h&ix8LRT;H*Ad^60h^Dx(wz6-PEJh#KTiwY7m`(Nb@|t}x+SPmH$C)@? zsnhMWlvhq^3SO?oLo`q4qT$;?{qBM+&N_YGV>A?YSW1%n(VdCH%xfKs1KfRX6e zL}SK02`Is5uzN12kVtJCbdIYFz8gA6xNZ&frR!~~d@}-{YFD;C=Y?6l?d81!5#zSV z*;c0Q zlT(@)C3nMMl8ubI^vi&!&NqCGUsNbD_f~e~%Xk9(hYpMm^1qo?4Gn(%L#IYwkv}d? zkn_t9`Em5ZZwzQXLy!E@Fb;VCr4y4B;_13x!g~v}(!|t6FCbNxPUkjYkMq)#0!}1y zg~+b?l+*37NkI3N<6F+{iHMVe@IG~O{Y5b~x1<@KTD_K{C^EkC3@I;xWYn!-*KX{; z@a{agPG8HwylC^aoGn2o*=L=b`&PActT-bAOyqL3?3N*U8O{F!)*HNF z1Yh;AnuLQ1IO_7PycZ8F;s}*-KF{TE( z7cj=pnpZ_IpEzC8ztbP!p)*?iwvwD8UH)EkEy%&1f`D@w5`MCB9_fk^09Bv8hkG~t z1L&=TRHs%gPJ-N>i8a`#iQy)L^R0>&t|`Sko&_eiC$V~WnrVk#zBXj-Vqui*r!ZTJ zb>Y}6iTjg`r@)oTV}t+42%&$@s%1zeK#G9M*^SVdmvFVE)eP^GrX_Nu83w<^snQ+^ zz@x+&SQ}?ShEe*u6|lKCtt0^yJ&q2jrMjTh&zD8l+2Wx`O>!nRP5X<*i68St>L2l6 z@s*+PHbl;6!s5D&L{+8GKGH+s5#QlZ&GsfjL)vW$hFm2}pkKf=8BWgu*;ezUVvJU8 zcFC4CwR#@TpXjI)Fe@kRq{f(v=WzPA2$a-@F)>Pj^_6uUFKrN)4XqW^ zyE>lYfc@;jvpIpxwbsO%*>6$WC4{hZ9h*!&%VH$LL+M_4qUF3sF26k6!M#O{Wo4g? zBSW`0=;hMi0KY?D7(CiWjq*%Mf`b_&SnKJJTnFXJZl=dLz-!&PYF`RkxzL(YV3^mN zPKD~ed9Z&J=J5dVd4Jux%%m_SGIWQM7?rcY9$bmF54exMgzEyM2}fOaxL)KSvVv=K z$iZ8)Fx)n~YiCc7L-XtMMhRN?n5UIT_5xdRZ^&)TE%cGquvpkTqz*n?j#c+_dE=?M zrhj3z3$^dNVx73+_Hj7;n@K z_-h5u*oweAS)zpdw1>vB)o6}UawtF4og&H z3*4nk8&9MX_9tD^;W-}ZJLX_p@6)gLfwekz_Hf-#aQ7C?kHMmhrKCms%4wkDg+I8n zV-}{U8?k%Qo0|c5_&ql7*lg)^yM?`2b}tWC))HeJr!-I?+W3qg2O)I%{?N9k|E4S6 zviO($`no26^>w$2yAC6A-&areWQAIf+h^NLb|(_mK5yI>aieqw$p{ftqOpNg;c=8S0EDD0-5COu?D%FoEEib3(}h(Xk#O z!3oU*fkEg7QkJ37AZB2~bkC;cy5FPzcBF`7UCp2GJSEr4&SE(AhUcraA#E&L^B@Nl zaXd&#QkNvB-#dh4&f=f(2TswbS{U%_f@{3rE&`LC&-CvrC4RFM<#)q_AL$ukmn5<> z3W4rfSWdq>>v~GeQybsWd~gftK2f~b6gh}~-!)rr!3gG*_}EcO^~@B!D%2pYeB}fE z!I$G(g{oDeok0~0>_ycSfK%D@RLLuu!MNjSr%0X;_e%bmi{8}{Xa()q#Jf=|H_H{i z3;q)2?fHEs^|7m4UZgU7vw=v@y=b#+BX=`xXUxOvLS~`(l(C#!P%GF1t=1Db&-m+6 z&Vqe2%aF+zL)`1C@kRS$pX?yagQqmf9XE!NjL1y4uG!?sz*Py>PBIwUt%hH9^h%jx z7~pUP)!teZa!Vgc8k*tgyP6Afv=cQB{xxm;)P?63E<4~nWIXB5<}-lqkS(tBept~H zYhv$u0KPTYuG5ZpP^Vsh&0sQpD)?UhFTxb?+?ZCSr*BubcOi3$uBq; zZow*B{c5pe?Md)mbQ_g?y8ao(sHdxvfZZYx_oY5a+35GZt{q3(jy`OLldr&hO}2Y;+T^h{;X0n;5A;?I@_FK#6y4wO zzcNL!aa^zn+?b}U2I+J+1X^J#Ji`B^)&n&3{CwG2wQ8pvjmyCkZkW1s&E@T5f6)Gw zct>b#`_6X6?lY1cv039c2e__BNB#K|IOW8EKdrtWuIqS|_qdEN5JSUa6b<+Xr?+lKp3m$yQ=xA~_N zq0g7+8UuJv#tgdV`=pjk5i$!tWZF|qQjUb<67$+^RDvu18l{GbIt-}4kq>dU10kdD z`VM?PI(u*BSaAG<&R!G9bQo-KUV`LypbZez+cr!6xXicm1L<5`>iD4*2Ald(Ecl{T?Qoa2sx7g}CZd~7Kx))38_c#TLdIw7 z^<#ch_}`%g8e0~%Om}}Jtjn@PV+_yKJeQUcYNA_&5ro?SVuo-`$n$Zic2Rt7?573z zu8Y?Fa2<{OOqt?~n@n{i5q&x^RRa{`RvYqh-_RSk-^GCJUZ(S(PN$)upC2a|ME&AQ zktmdKw@BEq;yg__1H-kykcI4Qc#!lYqgVj4qOMOE!)|o;9`z>mXib7rS|a)8R^^lg zILye=f=fvZ%_Wi(du!{dWz&872a zMQb}EENSzu=q0Fjd_yM1ZX;xGkKC}%LKF(T#{jCOh`HtYR{2EafGDNYY5X7mmY1fr zx|yWlW}h_p1VnpOlPj!E3{$IY+lNo5X5B~09`){!f7G>KL5M@hHOwfPN~0_;T$|hs zv_zfEj9jVtqm;EYLe!G7ImF3M3qU2)Qz3-GfaIt*rdTG7Z_BFBn_)A+?dO7f^#q26 z`s90*+M_IPX$Xj9{iMNVAZ~;+?a#GjRs`uO?-HtRD$=Lv6|AK4`34C^iEXL4?d*dD zTnSZq%f7}2f4OwO!(Dl^%M6)RlBoc6HIO1UDCAbe%(lX!{BsM3bi?fii1-Y8Med%b z-}uUsbgkehqs!i4w`l3!aSA0lqu8%&r4Nh3&OX||a^YyB_a;z9&`^s?+tgpPYsfY< z6Qkx;Kcc9^3e|5)Z~x-{*MJXSEf~n^-QY?(rc`jdGZ$L5A8*yl%xtI~IwG4oKnrGp zBWWrV@IT3UZvNFw(C$dtQrh(4@!34*`zGILQ}UN9N1jbA|9f{cmZ3}IH-gTLs)J){ z12m3!c!$u|O(7h74>Aa!Pa)3#`dxVDKqldmMGN$&V9|CXEa%SMKY6NV9ni>QECw*- zM~>&memjU?ZvW$zDU`O{_8%~b20wqt4Ejw+FiHDy=2xFSf-}1CxWo08Qm_pB&!|VB z2HG-)zUmooua#tvdL#Zlc`$Hz*1S(aay{9WaAEA-aR$!lT=c^whfA8Z(Q$c-Om3eE zLUj|u$lQEsuw(<1vL37i4!vtg!7)}+0*c8Ll3uKe`K&$ZDRMp+Y&y`>PCig;_1@MO z!N^Z9h%hY;(|9pyI=nYsX$i0#eaC7 z*sF9&Wkvvi2`tyk+uVxAy|Oa7)p7|zB@|6yAs1C(uoxu$;eBzVV(hwyBnK|>0?v07 zTFl)BkU9tOLxIDD1^CS?KbH`2vK?Gm!)LL11!}*@LcR44Q#&kW3~cTd#4he~HH;gu zZJ*=I$>&9+8#A-Q9Qrm=vKe9|xotPTKVcoHM*YQDaGXjsq0HxJK;b~iZWNO)Q?NQ- zfs6X&Zg&0XUd!s27XH+e%33xL`Wg+^*xU?1O+r&2r?zo$=9M_1mVM zIb2( z42)r5%-Xi9NW~p@-~b39B<3;$38MJiw#VzJM9)B-UQrt+(ZihS9ok7J1F49N_H|5FEE(~b&A_$qis!3; zI~R&mSCWwhG(NlEgErrM7EJxhBxtxh0F{7fD9m$XnG9=h<&40xhDDTO?ey^zuoOrm z7mK6ah;e%wtR%d^dYnSY7}cfjq^{N8dr3g+WNqLGSQ4!_@un}r0tQGA!1axJQAv`? z*e`6L!x(}O12EUsDr(;9&|1GH8%m;Ri?+5<%)N2dhRO*&0eNg8^E*$?GH1`mdcXQn z9vJ(0n{P4D$=EzBl~Y{0y7)d!x8Ju4lxOsxj^8xD53BdZ>N%>z_gpC$$D0m$(;;s< zWYHnBAU@%**4>wLV78{1El^=)6B`8bBPB~vU$`Yx(zjWZl($GbpvD4+26ib_3{9!> ziGjt^ro_2F0vqjFSPT(;1Sb(pKFg|3f#lBpcof%jle>?E$~_x9QhZHq*#L)$RkRXe zofS;5xKA;4%K_AAzmuGsQgSUzyRhXOO5!pu*(~wy3q%l7ZN&XBLd@@3oPiLZCCLIN zxeh<>J?SEkNvOJRX9tat>g$oR-MVKqe855r#OuY9#iA{Wp}3|OZ4X@Jo+=YB#jdI` z@BnydV*&6BtCD+zQlflrunBDklro$06y2SYso4qOl1A#2tneu-6G-LuYXs|qv%u?Z z)$hlBXM=FA(+ZhZ*flqEd-A?3JJ5K3RD`*Wcd{&tjp`Vdb%ea@6coO?KK1%yOa>U& zH->%#1mr?JU|kNb-2}D(%=)h4uX8W+U`^>wuT)|NQ#{Hp5TVf<@7x}qx!nThrk<+> zqPuwG+4WgT0!v>M-)2^D$4^mc3Uz9b>6rd&3$*KG96Cok#x(|boa`T)p-`_C7go{h zTL2?gs88F`WJe)R7Ato2bomyAc*InT|BUfV0lWT!O|A4uU^`Frb+-V;dC$u2cw(`U zDfL~uS$K;zW@;P28;7e-bKl7jt}P#3w%vg7bK)-C_&)fgGhFW-a@m@v?b{mbIAwo| zvor_Vw>dC!P0_pL1kBvD7CiTcdrcSXZ-t*Lw_`kK$~TuN^Q)2=8^F4_$=2%Tm8FSG z+F7gh%N6)6DQYt@Uf3!!A(rhMQRzGH7T(Nyy z2I9`xH*UAs(drL2=aNu?rc=pLjD(Jd)^&_EIaSvCVfIEXNvinA_xf--Z%z(Odd`@O zxjT1X7iV|0|L%tg`xpr*k>e37x4#ESfwuZ|$|WW97;;-cv;y$^+_>5nd)clgg_p#T zZH>nnC|hP|ZFVp3nW2^uBv{42WR(vmbi;V*3DZHJ`}YEkJ(u`I*6#1fak8gUO$o<< z@JJ}(EbW{TQ`u3-z^NLKp5IO=vA0|8-ZCPu#;5g`+_~{xK(hCI5>il7SGy8D+yHds zSKfg)9rC6_-gL+h>X2DvpYT`7r+>r8a*subwZ~*i_QK*`tN*pPfJL8C29z|*y0RuW zzDs${_Eny~1{M-jN2LS`1fNRmeUGI&5h!gdG|yn|B>)11mn=L2ykv!h{28FTCXfK5 z+;0U3r!_Z#$&{Diwkx7++{BbeVc(}>;tKe6T!!IDz*7u_cQx(ygwmROC9yZ!EJ3af z^ZU{w(*89-ymLluX&X0i;O((tP!jW`_Mg7#q^S& z0HWd%1>~n@SIU6IXfmR;=V|q*&no#b90tWQ%2_X`e}*Gs>!D zgyZE`CKGp*3OCAC-=BA}kF^b`A=F>e;@FVJXZbYC-e|DQi$OZ0Hv#w2{4?6Qs8AY!2M_HSObr^1Iu5)~zi?<=43~V5-HiWab#Vjf*(k>tM z6?LDhd(2*+-(J$$`a?CWC0heZORwX0&+{cYCfuCV&QWem2J(_llBd=*18pU%oT_ z235E*nccIOz>6MMxKO9A=Sq(0aala z_sJc71VS0;=`pu4zF7YfW|C2>=DIm`FD5OpT@Akrqv!5HAJqo$8o)mSOC66Ngf@t0 zDMq!Bi3{0P>|XQr^5l15IRkO;9?LALbG@cNC7_J>?2WD6x~q)$3cSxwJLb{__$rLy zzL=QglDpK8$<5@}4hy<9cS+X)e1#`?Y4fjh9hFFNkZ%fwZi7E5D1@xvv-gL;D4zcv$0%5eDe6;SroFidHi05)`U(wAo7Ygfe zTnsG96PM_dqQ39mvE-b$!}tWQ5`RZ*PI1_qOiWBv0>a(6YQHI!z9>2tAPX-y?M($y z3GIS)b8&REAvl?V)p4fh#16F^K|4eQ&aSd?D+C;Xo04dR5Q*kKfw=Av*mN(9*c8G| zcv4tP5k=Qw!j6Q`-WEX{LTR?+Ar#+JrVr_xT*L;VeN9u2VTPhj9w^?j52u;=$q4Hd zK`}ffAe<@pD&k)&6@wLdd0+M{K2g%hQeEG<5({+f2*!lC2TXfY#09orFe#OAc~(N8 zD)g~XXYQIE1@w}#bT+ZBFN#U3ya({5_WLF9l2Gei6SueL-3x~96jG8`D(?`QR>?rLz6F-bHR>zWx6?q;f@ z0-28-2EsJhJ2DrhsLY`OSn6`G4=IT9awYWVC_CVBM=_82F!pVLas_D%1(8{I^YK57 zEwe0o=FW~(^6A*E(q_zgv7@|V9-0fdFny@m%JL`hRB(nS=-oL@m3A-w=Q z|53FB*EHsoU!MmQE}YgEfjz6wB4FXaPPphuygNU)4VHQ5)R5*{C!EBtw03G-zK}Y3 zBB{&E7qE(14c3?h>T0bhXTdscwIfEoT#Ac8lFoD0U>{-WCUuEN%(-hRH-_2K=Yal3 z{aXK-Fjt1Lz5=uZMw(KPlkW2_eu+)xVRHJx^w0;L91^f@eoarcrUGHsNaIAhc($az z+yM$8Fy_PF6+zs*%NNx;D6x0*Cgv+A{mkSmqid4`fE}2i+Xw`Bv_c)tyDCV=Y%sh- zAWp6NYn=zpzk)o9a*g2B^BAZ<*vxPZF;-p8)&ZlE{od87R^Ye=!nCm~pd+h;J_V+7 zoz%kOCo9!!$;=1RqwFTwgY zio4R6v^nE;Qd*cGabth84z4y*!*Cmmm**ySEPOqwHCz}rVd`nz43!q()m*0M!BXMrkz!xyQ&=(k@IN`WtHnDSaIE6csjRfiW2|=PZ=V z(;=Zsxel}A=k%OU#tggu zUeb#8(Ry*hPIKoI6PC=(xWhQ*BbDQNM+(KjJbiOY#IOV20nB9KK8rGrMG5@mv-rUm zrT~lf#Lv%!B#;t&nGe(kn7ClLa(*spszi0#lIfD7t2vmTiC_y<(O%=n)=S)5!r6BF z`P>vC*Oh-a~U@mhs(bL@}mz7=YgU> z8Qc6dU$XB7aI`bPc*bxX^}`jQ@48f0`2#6SFoF{DZsyh1!QGO`%mz?=00Dc-F@P1= zEQ+&Wml&l7Y#bb-ADxg85W?zalI@J$OkQ&t-|w&avZeBM2e$R(T+X0EK>{(lrH|pm0WWZdrN!4U(VGk@mK zVURN&1~P04KHRealx+%{MBTRfcmf&o{^qssB-zajuft|M^L3red^*|;U2`MQXD!e+ zU6bd}e5ya|mA+_huVz)7jX;bwcLdCZ#1Bx7wj-aEi-j`{+CV(Ma0XU^9S z*TD%h)m7(?ylNxU`#QEO@O><)b@zF%8Ec%d_3AsvBw~2;Z;TBqd2;|uBTd6kIY*XV zGyhv}Z6L?Y54hJsbMMGSZEX(qTx;=j&BerS1RQ1cC^|YvjX>aGCt#(uYaIme#`VP0 z=QgPZaQFD1j3ZFznVQw)D$q(JfkA+!U9X7!iLlks!0rKiSo=H0Bp~^vLyYt1^`%3; zbchA|V>aZ7kZA1+sSegxo2u{S%gs08QB!u0IT20+gUm znE8i5$Rw7~;be}X2ppWyS=%{fL7AwP{`_9Is8O3+W>1m!hC3WzGQ@Frcs8zuG> zqqHHAfS?3f=}X$-u7XT`F&uwlF8mgd0p@bH54??;_D9DujcugaNIBZ>5|(R+ue*D~ zGiJ{{`>*@^58-?>ki4{~6z-Z3Yyh%t*p*?#?fc!Y2 z)j-uiz2*#XVLYn)1ZhkkWnNFo8Vh4mQr<~`3pg0Pp!v*+a`(+RP|#tfFmgaM^wqpO zJDP3F-|x49W&Ly%uof9Uqt! z)tdVo+o!;T!ZN~rSH~w{dCIXa&Xi}t8UfBud;t4_Rd;$<7-#i0weAY~P`BphA!f46 z+?+HY0RPodZXTVvZS`qGioSVe1HmMl&taR48{k`CQvYiaRrr%hTgC@9mP~C2e`HUdC+=IstuqG<2y-c6+W2=53L%t)qKP>+|xnFrE)U4V1 zrpQ#V#%KC85U0FF-(>Kt{Ej4S6W0-4&p_dN6rm^Em`$^s(`;=WN5GIMCd-+;^@!J~ z9~nEF+)S>s{qeanuW$Tyt&aeA%r7xH_r5b7cf!PxW#m$y_%`3U&zB9b3wXa^YJ<-^ z;4WaeY24MiDy74D2SrXQNS)`Gm*;Xm4?Ig+fq`*01$R>%tVXx zJNqt2`MHM)_AGib;WEHyL{$t@&ebbh@ym1XDgLm3UFkuJX4GrSo++~M!_x<_LQoAW zl|%v*CIEzR9hO3!N9cJxffxg`B~6R0Bf6$d6+gg|xvYrDtsQi3%1R)J|6VGMGy@hR zR*CP`fM9}i11wOx69f@EkzgD&fE9QH9QF<(@BGk5V5oj#+;9^nNO6IqZtvKt6mLR1 zmTsKuQ&O=Q?XW)qLpcVweD)?lWS$IQ>#xtR`^!rJz3oHBJF2ElhJN=vKd7 zG&)%1l_VY%|$Y-o=tkf>qiP|Ec|J9m?I;)%}z2OT9XM zBr|Z}Iul<J-#K_U@EMEfL=0fB zls>V9&vU*p2E*^=gljX>TnZSyJR3J)vvDgLcvIWew{$%n>OL3K@QnNTLGjb9fdTO* zi;_w;(}tz7J7EwrBf=ZzA2#y+?`I=YkCqW;Qtl{hgOQ76<%Ko#?FMjn1l~klr|f5N z^&4TFpJ&&oaOkF7cHiFsH*L;utQ0Ug^y@?*44e+&kQJTI(roN(;u|D=IP!H>-U_a) z3&S>NDoYJi+L$@TVtr!XH9oZJ9M_pkU$A4Z5nJ*_sjhrCt!47T>M$qPPY<1IYAp;P z_1O~0BM%lp_|)d8;4M!c1e!qN5rzZmn%`|~3Or~m3ebwspFE7_#sDmJtv5~qXybV_ z?~lol>K*fDyk|bz&;;HmWr_ZL|C70DjTzxqk-OVC85QHyX)aIdSYK|t9yb?{{&XwM$dp1T)y3Tky|O@vcM8(9Eh^xy9O{*)CGj z7zt5?|NP3#cLQX`Cxu`;5{4V*)=a7?@=kg<+o2zs-tHWcH|5eA)2!okfQI~FM$5&v zBqj;rgOe&c6(RG`hn;_*;Uuu*j@dY7CS+PG&BmWET4FsPH}Sf%Qwh3>RCI1<=dEr+ zO$1&FG4L{`Itn@V;RgWis}$_yv{L)bN+|_sAf)A#fWLA-fht<@JK%W42t70Fkl_As zTqh*21nD@;0}FGur82G@eu^^dfzQ+X^^O03;E8!j+KL3PRq1-M{MD`d%^ zv54BnLmP`QrqR`r*_;_S&9R|`(%#nsHr$t4IpCm^JYRpMi2WSHp~_pPr`^zXMmZ)( z*cgl`2-RpZRK>stf)}Bnk`r~2yS1K<}5OAVGGw<@( z+v?ZJO9#|9&ohyC%FP_T=I0A$US}EwK5u~_*UZ@FZT^qVi|EkiwKaYtZ`1;VYSUrO zl#?(Pzl~nZ;xJyuvHt46qDe0{VI|7GY3Be~!5}4;E>C7abEc7Xzg}9$q#01T8k3!k z#hqhgE*uvDDKUe$@ikMk>Q!%$Zy(CK*IJHr4@o)W&yB>fP96y>Q}>ltNqU zuHd?@cD&on2Q1BcbGp-=zjVl#4oTSf|4WBhHtXi8W%^sMReS%|r~aM$OCLb&Sl~H3 zQ=ooMn0-(}j|A1bo%&Nksog7PY8>hb%7jdIYe7&F%K2SA zr})!~ZLTSsIpCY(izUeys;IA+p`7bC7{P>5tUzqnvA>ji;4hZIxs@9&*(30xcV(KI zD8O#3JVIzq92)yV8Lc{mvM7r`1v#zk-Y&lbPdD`}6~!DW<90#ZTgnc6 zWfs@@Q(jKj*8wxslDb?T9DSCLldJdB)W)JQ*3T4Rsb^xeV%3((m$lX)^X1LEGO1nP z8gGCdJ9PkVGtmd~@0h1j-(WmGoi5PPTaQ?~0xe>;>aUdVBx&U!pPH^OF6MeB z_%cq$a==?b*nMYP^CulcM5!tH_!Ca}VcVSJE!c>ks(YUbUH2~eC;{x*3X zW1VV?c@d&=oq(>@^xWDoe7!H$ah}(g=2+ujH|i*feD#P_A>#{I0pqXNldYEi)t<)Q z_yyjU2f~dAgA$0twG-Vw`GA%E9r&3O9g-#5JEt|+A+%Lkm|tgR zdtd%(w>kPwC4t17xtiH~H+g>AkortJH-Tl>0k9osaLlbuJs-^C=Nto-Yzs?l8H&8%=iD70uUrY zfUOaI%8Kn!$IMp!+ZD6d*_D|;@j{+mKOb#FgpPps`Mh_&(<1k7WWEQR2>$N$ePMx_ zXVvW~py`PnA)B&(j7=aMw|2y3cF!~HtnE9_%bi>?14O76WtSPd(=JN(`S9p_?+i}2 zGrvquLGSH#x?u~nTmgjeY{K(Qe)YDFT>6(hrxcLOp?5}PSEX5o3yTt}(mb+s-Hks8@{O+yglS{BuH?)8J;V7Tpo8MH&!=-p9Xa+ly z!#ti6_!jwVGw>AfnIp;cJ!Np?G@s8I%2m5Ce|oC?YnjY~^^0;xK?D|3Je1)zc1pi* z%}J2KyY$9@?xKW6N&+IWFO%<1{dYRD6wy}cG4U-r0 zv}Jx}AO-RU+5wUWsZlnwiO7$*b8=hD+EX9aCEAgM+Hn`SeKLd()?M|ep9(?>E0>O{ zULN!O^wkQKUjVG}an{8XRHeOUzP=-O+w7VHCfYi0>K~)FFYO7obFrDoGeumfxrY-@CS+N!bNda@e1!GV6UKvg(@R z+vfO9NC8JTX21*)rNnq-YAIQ4DGu`INYGsY3EA!tI)RdOX3BI`9GxGV5-MAJZuyzV zQu19J!tPcsI>53VYl|IdNmui+Dy_=+Ar13EsH$x{V`7{6?vE5G#a10g9P^`l&rFr_ zQ3qw-b-!?9=S+6&P*?5WN_SH+B{5Zm zzNSpf75o;!>)%o}7~ehCq*N9haVQ4xnu6G2FK(HnHT6m%@G7E2{MzXXF$1G8%sc;< zWq*{EcaI~w{>T*dV9e*d;gr_Y3A_NT9NcMERG9wo-T-B`(M)pR&4I^2u{uQ{(C$rL%2Y%O3tO7^UuQpBZdSuRYrzIkCz`-ss-o2-e4jdSG> z8zirp@!hDyf)Q$T148*U7872VjxU}5iOI?|cmGu%WOCQGgZ_K(csQWFB*6Kw2ABeU z<16XsJ5#x;PuZR4+dO*%RQm8(N{|4;{8m~VV8VQT^5RY`i0v%0Hs8`^m?@i(qL7=9 z0hglNmE1HeDfJ}eHOdpkYQ4{X!$zVNzvq(%gD6KId&ijCy|>gUM+Ia~ZOzRYwXt^r zM&B3Qz=-art_n~tu(8+QS0^Fts#oS-_kR@qiz!zft4!H3=*qfd@Au|z?C|8coSqM7?K+DOXjpsoI%}!{nQv+)j{#58uhkM;o32c2dzS0BlU%hs|&%-7L6mrW#+8 zQa_R(v5!Dyet(IK$h(eYbI!zUI2K^AasqL4^r86?xV^o97nO_6141XV*}T4BuQvjF zt}G}txZ}sCF zko;ubf9a6s^_LF$(jos$hgdg1bFJF#XP*3bo@ob|IdhXqfV7@yR)TDYK^bM26ryZW zOtW(xP?rL<&^dkYebGXnd`SfLf#CVzk8>0`o2jz!|Gn~Kl~UZ)!u-6H8J+-3#H`mU zWQ$r1I2+k{96fu z^^s26wIOn4K)%}zwIS(z(K<6MdVg8pJE?OZvy(BtI??3`Fxfo<^|6OLK{1s0hxyVP zxPAv^<*aV zl}}Q<&-3Sd(+P+C#0Dx_C;qcFR0pdNLOcgB&BZn<2O#maB*KEEn#YsaccNmAi**q* zv|#Kr>A$q`YcUwNv#}_08wvru{c`}k^4kM&a*NpNC(_ByF~BxpmF?#rYb^*|f{?w0 zv7h>eqS&BgwEH&%YNV@7)FH^!)uhnc03uUu|OB)$L}pSs+iWXB)Y1)z#d7 z#n3;${6E&K-~?k(cgK%?p?kVzHxTn9E1ZnwEisEj*H))g;qO*ii2ORZNrNu{}5+um6p4t#_^ z%%>v0n+buyHqe2?w)7ho8NKoOe9ipQA)VFxr9-}SNIE2a_A}S-2ku6JV;z{R76LZk zvPb5_c9G==n~RX{=&F?g@(Cf<*{DaRmz>f|)ER@fBVZ?O#Q-UQjz}5*Jc6KT!hB6) z;K~t~y!;Lb9kDH$dQ!3p;I0_0@oQqbYKNK1+1lwYShf6YMnMqNB@GQE^M<^KSl3FVvbo*pwf z1zu8I1RWum*(?)m$(JvL^Ns^_!5+`dS&*6c=8G4rpw45qRK;KU-|7DoRv=-&Fokr| zM(kAzW_)0#PwE@NBusxrh_1|JzyhcQgzohT_M$U_k40T#_lzFK;1d8EyPVF?u?6b0 zqik+(DWuh(seF4kJNq)=Pp&|~JSJdIP~~{tm054v?7K`-bK*m(HfpcZsU73IgpQn;@nPUqEajtxrB&udhGS<~4vype__lEs>2SoPySOF6;!}&l3o?@P2qZ$LA z0LJ_mu4llnfRQx^UO&eedyl!6Q+(I>a{4zVUrw^NKUUAfjt|uRs9dZ@zNwivjTRlB zmc__rLeFmw5T9xGPSIndgByXQVZSgz&AqJa+dJ09yx9oav3CFr%w_e=9in-8{mxBd zOsWA9CSm?+=lVu}9%90Pm5t-lbhLS*{%tUJ`7Dr3?p6}74zhEWflzbOhs?Tumz-KZtie95MnKUfXFVCE zumaq!<|bL%^eqMbwA%yHF6RDm&MF2x$+{6J*tt`4S=j-$r*?F+Bgmhxeo}ty9PmAP z{%nL|ofq?&=LYwbSXMWVEYZI!m-U_H8TzXT85Ot7ko9Y?b1( z>RLdS5{%8`xQ}3_)vtlSV=K>GISRaaj%^n}S2FB2U&D6iYx|``4BVFv`O+b)4ry8a z%=P<$I|3~8)%MoT)xqc~GFJlp#AhnulL>?UVZI;1MG$pYCe@M{zY7$2CO8i5QWNro z(vN7;l>aj3RP)~Mwq3j@A5Om#9GR0cy%M|&Ffh?Z1YU}@sLmApg0;)3`IXXo`7_YU zL;{RpaWa>c=dR54`EeE8kdWB`sDaIksNeSN!x<#ACzzr-kYcV2;1lQ@b0)l&P|ck9 zz_hogAn*K`uI-L73>&$pZfuDkDMXCQG@)7_JRHuIOZjz}G4OtE)Thg^Ry8u>tG31B^y3Hg>oHfQq{ z%mqMF2tFgQ1A?)F2j;;{Sf$D6+KY(%C?{C?sbV51!B|%+j=2Q@^Ny_@dqhw-$5y5|Gg^vyK45E4J?ng%k}t0Tj)rUP4}k zBi_xs-g@xP`s~&BYhJb1RX_nNhq=m}TVLk`7MLF2PtTNsC$O_|F71U2#gUB2?JwqX z|7~J8v0ecam*)?|HaGvZFTiT#k~2FXu(`fB7Vq7sZ}Q!2tz^p1Eg}EX+aupm-!+P> zq22rlu=}>M>ZKaEvS7N4%-E1Ma{+X*h_8TIZYhEN)^Sf7Ds!xJW((LdAIz~GAONv7>=ew&qypjvccYeqkT;N&eICH~&+AFu7xlkBzVPR6@s{EzH#Uw8kp+ zStyQlF=XWtZT%HI#7_@{nR`vF!0sLtO6Se8ot`sU$Pk zqX}U2Zmspikb&mbLYX?|Pp1v6X$xLQf?$tSaf4;ks%DKN_iVg5v zR{L#AmNWOYzNQE^lzMJ=6_dYAOwbz9dz2o*7t+-fm04|T+_Zv(+5_DgU;>n-{HT3J zqXxJcD3w-+1(wR2*Y{eRlF)Cl86A-pl3OwpnKOO?a07X(@XMDc2C%I8&N`rAz4`hF z_fcn9je!4;Io9*{%wqLfm1OQJM6mY1Gm*zMXZq~VB5Cds=y`N>QhDCy8bquH=H?=( zqsYTCUzv5aJB1wZ42<18Ti(8UZ1d`KesDLSGGHEq^!N=6s~__HETzk^EcLl7ka{V9 zAb+?4h?vrj(6hRRS1auhNgS2?}Tg$d+ew0H|o3+KL4H z#udSs*WO2SF`u#O8sK}xzG?ur*PLbo48bz5tBHn2@h^S6!cV?J!H6ytDvx2Xh*Tc=xA zfG1$cV4BBD_e_bYfB0AK9t(!3FJtO$TGSzVp}BMA&({3C+L+;~tvk*0Nn?2cvQ0G0 z$`ef5MF~rnuC&}E05EH8mp`AUr<~)uIbBOIH+qpdnXg~$+>INcs>2WcL{O=rG&gGPi#|W0X)K|f+3V*0W#y{ zGsk9K?x$h#ykp@|b7cl55(!-Q0yB4jDDgDU*?B$`(TH*QPC=A;zH|-w?Bzfm$VfR~ z?Lrrz=B_TosSK!9$bglEe@KYJA;9;;;MLWEnG`NY%YDJZ^4OIwAmNvAk0}ef-W?KN z|D1gm8_>N=j`FV9(1daQaM%8J-FM0_NVrkAWt13!+^NG@%I?i19lUHe9Z((!m)1tN@pkE*b1mg1*v6A?R*Dyrt-Yo;!iR0aE7hbZsgZ zR;Llv{xu5JxTlCHgmU*^&6&;$RT=I31Uud{$HBQ{*nku??GRM#7^Ezxo%g!Lj`*Zr z%s1|$&jL()W8GP)u^BnWgZ6Gt>G<{6Tw`Z;{!>>`$GW3my3u;LmyfURsGRprilpDKj5!if$Zj2gqy3 z04fT)jmzdu9{})~UOQlY;S-p{{QTZ{nlq|x{V)par~K-2ak%TlOwLbC>Ye+VNwwqD zpb6yz6O?YrlW#jw=;}9f+OTwzM70cP-Hpp#xiL{YW17EP^QHWD4#IdiNKdoZ{_@|Q zzUv2lyPj=qT&!V_si8jrS_(cB;_jEft#p4{n`8k~eo3ay5~CZ~(>?MJCJln#0p!Vb z7|T=AYuAlTKuNj3fSo{qd1D>55opZ}sL>a_V*(v8tfjZfEcwdxxBB&w6@X}IRRZTH zCh0xX;P~PJB{K%(N~Nfg|1-M(Fc$k>WcNETwlU9}&5N=glP^7r-F^ey4i21-$v=oB zO@=+Gf9oP9lOxI~t&{qUn}=6a{?dfq%=|u?2gwo5Jb(Y61C)wP zzG*`YV*OTXoGceUF$bCpw|l_Et4&PRJQr9<@3D$Bog$d?XTNh4F@C$3Me^Ak`0t4AmtEKf(`6k&QB#v_nZDhSTr zDQv&>!u4n)K*R3uCZ)jr+usPBA}X1UO2IIPeA_8*C%s7mC{HBd$I~Uiy%VspM==~b z0Hw1-cP}YE62D#W2uw1`t}^36$CC|UQDU~wj^yr&ol9kqT&v$5IhNL)v;Y{R=R^0! zxA{IcC-$glxC9XP;wp{F>I`422ya4uDbjMpSwbvapglm%rZ!*)^0%qXC3A-yYSUij z?gJczTlHkDpbTR<64_nuFRGVAs;jb)N54MSX` zZHdo|I_?6e-FU*bjW4Hr_sqw8=IEZ!Tv{^hP7YAW0GSNwrA?VRLX%%_P|-J?(;F8)dENpofX}+TjDF8`JPe4fiu>s}Q>xR#3Agl&|gH<|uH{-0}kbVxAee0u!G3u-(na?3t^n*=ED$;2Cg!nB)FZ z!mEtP+`VZX`#0a%q)f7;|0*wr)ou&;_lPu1D|_r`*Rc5o`v9$331WP8x4No}c~IJ& zj>`)WcI~79`mnBI%AT-#St{PzAig!%|2Lq$eR%oSI#Yk;6qs?c4vOmMEo&ZCS5PW< z81m^n^WVAvD2syC!Bgj0^hs4jrkz{g=Chdt*z)l-MkT%e#qneWiQZOs0a>#V5iL9I zAb*>S9UW()n6m(}E^b~=Vs>S9jRGT=+a$NZzjVl#4*Aj{NwQUk%nv{DSE%Ioxk!;a z=lYUgX4WC%l?&KlSfcgwiJIi-F+t=+`R7V%x#Pz~Wpmxh&n{XZ)tPj0+uI)rW+J*B zp+70q^5b1IS5S2Az+(wBJ(d=v$iv<{=S~uS<$pUf!OD8B&H zM6e~fM1-XzFRwsY%8)5?)fR!J+Crel3KjLrWSm3#g;Gm#B&>!FBj_@P#3pPogv&_t zB$`h&t3JpivT|RsEr47MT#Oo_Tf}FUCJ#^9H~kb#(C+=-u9(8fk1D^mPT%P2_8Vqr zTi!SAxRp1qppj4CoWtzaQ?%NnPN}4M$e3&a0$O|h&Wf4|LD+XLY5sRQ4#=t8CYwIu z_ZK6yreO*2HeP((Cfy9BOlh{8-+u!0)WMcQUQY@LYGX+$<@E?Rk5X#&)sO2yndMbD zlY}Dby&Ha*JG*|c9oSQKAYuz-#bD+`ccL+_*OCUSVG3&IiJv>ucEH*Sepf}DSq>nP z`>>?8`P0Qv-6*8yZRe^MH9UFG0+;5;uJ%tm$1_v^0$c$L{Tx7^9Dv@PQEvss=4hZk zh0Eu!dkid>NC6$#xLE7*@Re5O;GUfH55UD!^Y~jw#g&E!=q+itHjaNPb}*K!IdnBn z;k=SW$75~HkIKDDI(x+g7TtVsTEUYtV@tL`;~n#JZr++lhmPVi?yo>mYo$I8bk&Z& zxoLMn2^wl%0bZ>^^?W2}s5O=dhod4++)zM!C-gJ`6M3C1GU~j>sEzGhdc2Abv-pDNAwWAhGO;f+N0n10W#x7X9 zow>HCTYX$I?VZ#^yG-v1;#s$TtXJA;3~SxSG*=YAW90(DV>-7XUHV>NN8kTqUg<>d z>Vyq_5!3AR51aXt(a#ykes5MaLMDNJYy`4I)RW|M5&GoQYFW`BoBS^w@})z*bjUyH zkXbrE@z?0`pLp)yd}QH7o8MFC#qva-L(((h?FV$E{8CI5;P`AM;4($nk-q;g8+d?? z6Hj7rhe^5v7&}LmCA>+cd0)@w$eh1Stbm(*uIcjwTa;B1TF`8y@nbpu2mpZeOn0OeNH>!bc2 z;9_)Q0GWdBKy4~&0yZebz)V-p^v_HwF$pQg`gJ`B-cB>-BU2sln|Wp(Gwsse5~^M= z1U_JTJI9+cWvX$EOsQi^_!?-<|ERj>XB3O{@S#uhmojtSDfj^G(s=9F%zq2^DY&)6 zg#7STj8%vw$n17E@2=nf`@;vIyaBim(!dn5uycOt1o0TRoarZj8!(!W)*T~sWJcQn z%afbW_ZO_`$MnI`F=MJTrc|ToT;oYS0{{j#U)A@457w4*ehHHEwTfZeQNW!6yMOsF zGj;)=dLacKKzPDv9$Ts;QwbHE_~cdN7Ge=tB&!&XW&M_k$b~cKLs9Q&pHCE z%|XY()#ncYTrtRu(gTDGcx}FqiIYWZ)2)%tXyqww0r;j*M0$<)S;`>FgkH=uGn|=+zhy|4o$e7 z^*rP6J@#J1+McYb{5+jyKwM3@qz4TS0fGc~cXtUA2=4Cg?lMSlcZWcL;1Jv)z+i*B zlK_K5aAvU0etYl!@1Ljpbk|$;6d%PYg_7Qn`_cx4_Zv9_Qc}>2s!uoHuC6LQvutyr zeKc46L^-?w#vTBA5FPcQ#^mOb}=NKeelN!kHg@6=^HRbHFJhSG}B(Ei5xk_^1< zvYzR9*3|j(m5i)stP<_#+ql403Cy+6sF21kO%cwL(GZF+Ug4l1pg7J93i^;c4ayOQ zQHb0;cVpgs=cRJ>DW{%4)R(4jx8C3->C@Q=I4HJd^C|j?eeEl%UnBoQpl0-M0t=G$ zZkQW&)>Re)KF(DHP_hn$!gr+6`&zE@bv}4pcHD5ZkgwnVE2o*=cc`Zf14U6oNyn6^ zDX>E|kNFilm2wzP-m^Tw70k$i40U+i(=9Ul|5-!-6Jz=psp=H~wD0c`|A=Wlu^cVufE#**= z^eec>6L6-^=CG|CDs+Frl&TNQ(xk;T`45sOmGYsUsc!8u8YIA7A{wb(d{{CIjpp?Y zfSEqlbri3>Bs>F^|5tkBsXCQ@L?%Fs_9y(1DxjeO$diL9E@f zqcLx?BI0&`zAL(>6x^~VgUQXqF%Pin6JND{r)MdNhKurulf7POj~#=cGRPzS?_<~r ze6{4Gy+!XCBTTe_$9Pw3jc4TnD`{+l<9Jyk?#0WjRBa2hr)+qw(fmTfrQ!s;+dsrz zc#VnKIEXlc$-XTMs6}@H$jW3+Zk9GZ;doD4P2tLHU)pX-`-kIishpgC9 zONc>m`ZycU-NAUzA{P%fC!_DgHBgAFDvyqZg;$t6og`|};N-_oy?i8qNivCL6hek& zJ0z0Tk=v(3i|s&Q1F%#0$L)GLC!0_TyP2T&0QAQUp$(OEhKUMBL=-1v0H{+KG8a4L z#hk+~T!sTDG!RS`ql$%&5|#2x+YY#jQOPymDGV?#xTF?L%}Bdr!GE(TCD{f9AB)G4 zCL^JJZ$V`_G#Sm(U!-oC!o)<#?X6i`6}6Nb&Vs6iLN{-s*Q?(+h<1o3>-jQOm25HC zk;fkpR076TB`|LR(9%T;x*!qycwgYW8%Q|}=1y(v|1@D`cueD zbiX0tjO%l^{_T^Ij`Ju?2^i*Gyz_-15n(s&uaZ{AY3Psfarwr0jH&660RFLU+cH=}%b_~pE>dKrrBGoy$rjq(={ zfzh??HBP=MaUICQs1@c#j6ZU&tve&lo;+iZX`{}XJuS@{Q<{PLeo)CJfP8hwq zNlu!Q0aV?(O$ln^WhTwn-&U}JoO1(6qA^!J_~OnHPnf#bF@xa<*c1)IM&&N-mA zUDat%t^+aQpm@pyk!%=-CvDiZb8)WTn>Fqp4Y2_kXqvPaM4kKK2yg1SD0m@06`I-X z!ukyGvkng_eH59$un8!JoyeBEn#%(j~*{c?O=5fql8r{P>x2wnTWd08H^6(&w4y>QThERBihQ`~Z7!1I9aqsWw`+*x2t7!PdR7iZll=z7 z(5@meDd>TtmysYWFT> z-uT3QSOq_)co2BG9n_rRu!5IAo+?(*0gWB86dyoIDl8-jltZMQy>Bmw-ef%w3c$~n zH6?4L!=%3d%rA}&Rzrv~DGx}B_)-OL=IVdfln6YWA$e_tf>|Q)Nrf2ygab_J{ek}p zNkm3m|6hIdXYu2yXZhQ3`rGw;ky#B9C&rP>P!C!{v*uZ3I?jvl!20p6Vf`n1>RN=2 zLmo6fO&i_FvHe0CMnzl}EN5}kOpzbm?JQm!hTNL(rH2vhd34t-5WUO0nC4z{S;jnC^_N&i9Z(DT7$x{x!w z^H2?A@!!^Nj=1X|!Iqs1;b4Y6-<)D)*2pdnCEz>xSh2Gvzade-Dq*jpL2Oy|H6iH* zAz=Josto2R8tI}VFj@Z33Hd&`h$XUcFlA_^2h_Qz$BQ2IL|MLtE1fV*ejxy%8T+rc zL+1R4v%(h6>H<#sd1HKY2w^{4rNo5np)=fiWW&RG`R1xw8@x9c^8w@Je%cU}&$JC5 z->6l{Y=!C+TZPUoo%?ol(^R{s(j6Fh&HJ%fRNx@J-AtGJNsfHK`F`&tm5fsufi$Ar z)B~ko^dnWAokyGY3K&xCMm;Ok7l1!521<~|SnWk{i*|~{zXPj;p1bBgZDPxi0~3Uj zz9=-A$(m;O?UAQv(u25{iuqVRR(uAd&l1xFPR+~{?&OYLPcVPR2SLl0oG ze-OT8e6ZKrL8t*bNMRXseZuoTJ517vr<;1a`8~g>WzUXAM(p!zeiI3LCaW@hrh=9W z@+c+PvQ5mq`<>kc0-@F6(E)iCtNs*v%*1?(Ne{Ve?jiKqNY@D!UL~dL*P;E-dsHReKI&=wKOTRjv zhT|{4z4Eu*@gC*&iBlB!OJ1H90c;zsy_2a;3}|d(Y~Nj5=Xn2lg=%LBP%hku5JpDl zi~LB>mJCDo>8@X1kUwkZnkxMBxFvbLR{*3D%T5*9>6MwO|3O3G!|;NWO!w}KwPZbs-kRKjmESomJ1n#hh2AYp?9$#WyI$9zk4-F%``)OB z_KRBlv%_p({7kj;@YlUFT6f}ImXOqYv2&_q89&ij zwPDnp!p&R#RtPw4^;{$vKPer-X&m+9KQ*rkxhqu>76POx2zv8H&?Vhti0lcF9bhK}xMQs^=mBrt{V()>_p zRj=0V9ON$C`uCK!(k&Mlttz+U;cDG$H)KP2SWDIN7a?2nRrXFRDVJ%)$fXfMW=S#n ztFW@vOy=z~mPMGJ*}sNjDz1{3huZjggkpsjdpWxB%7A(m9NxBGb1HPX|{;x;&I*vha_zznGV2{Le->IHQT+uU?@hX z`&NJUhb1X9D^2FSD)*#KkPq3MJiPDLvT#Y-}8o291zeic`} zLeAT}ukt8tWI$%?zpJSe+_R(@#S&$PvQoIHjB4&c{kO8rd*esTMg?a_Q)rDAPBX{ z&{NR$q4#Ovi}v}o{5G0Kju#*G%oprdI8br1VFL&hRn}F*cE!0#U`*95#scm!l zEbToZXdm~Z70p%{G!E19sL`41g!eNh->zVIu!&W!B-97b5n*IwI)YZ`?FnO21 z=`(7{^bbJ|uDI1m$r74{Z4s(jB{2lUr*=~(E|oP+I&hDl%My~rV;eO~l(hKwh&R4!?RmLCBSzY{*fso{{f0TnT(Ggm_!X?-4j>Y4} ze*8+7kK8)=^RErt8U8&=0lH~BOW0Lh;`oD&D)A_@abpCX?8Ph;*Qp4#kU?Yv^Y`Mn zdjx!xmI)Fmy!eA$F}R$DHR1)0fgu31^xr?tTB;M4xDiR0iD;TWWSCi|lPZXZCw#v| zrE@6Y5?R9ZDZVe>BRYvknU@fynOinuHlZV^DK3Lo{yyd``2WnTP7h?Ze)}ATB_hMP z(*zfms$Gr;RjQV`ss7PIWrNJV7&2fWv8|Y8*oz=4xlrIR$Q6q4jJT~x?EV0?0zW(} z1PZK%mF9YOvpA2HzEP%gsn;h#sSx8R-4u`Colz%SjJ2&zcLDmqD-71IVbI|5Z%YAU z0V@7n!A;29y4BG<!{CwcrLHjG7opoZP#a& zP+Kr})ktX`p;FC(&uIoQNw=%4gC|iX@)C&Ro0*1;zN&7*rNL!;aF`EF#4ow}5;kg8 zS36Su+k~`oiBYyzSyEwOnomk(9bbfh^m}I*oDbv<;9y3J)5L8KFwxS27(15Tenjd( z^m;&oN22WMzfm?799-E3J*!RgpP44iR|u5{!zCnk)^lDq-*@nNnJT2WpLm2YlYZ+| zU9+h9`I=XrUU^Y{F>1a7udpj!i`{%UweBd+hso{=lZ&*qrKU&>zGS>|n{z@~XMA8I zjG=ZqYz&O=Xx19~IS2y&DpES?%91VtbNgo{k8-7e=$~>I}c(hWZX@311WA!#E%}&6bWMyDeRw5Jk zyNAAjetR^iZraweMUN1!TLJp5WmAM-al{9 z1`+dvNU(CJBH)a-Z4rCZ^>6VSU2K~T^iPrb-+H5GtRR`sQpm1jEo}528*-J#3EY36 zljHh}zQG;#A-o6^6esIx#atI0GsPIC!kdrl7ihvPe5p1K8xo%IG$w#4YKy?-pVum& z&gL+lLyn*HEs5I*EB~`2aZdL&qg&!aAO>`h8BwUK_@}**)$-jl?uWuZW`{oI!x}~T zT)KK!Eua8#W-g?lD?DF+{sFTv+qf~UPosfRf8p1+o80l19&h9Ki6c?J`l2$nID&Xd zb3Wkx2voO;4hrPnp_{b^nFe=Bf`AC}rleVK*JC&E@Hmkk96CwAFg~|cZa?|@dKqPC zF_cM8W_@w9jjCl^p{CT-Dw^q0YtgeOWk(W9a7B~MNbpqNu3Mj<*%m2j406O3Gi4f4 zvLy4=Q3Q%f8F>8hOLoAubfa^!+?PYqu*z2@X!x-n6i?q(Z_IPhEKc(D`vol6WK9yB z=`RpQwo8)!9_Ne@tw#K)+g>m45~rur2Bn~ZfZD^72Hs>A33>-XV0U-}$aad< z@4Fra(?QS#?}T5Hmu>~YLy@`q6eh+OO4q4{Wijw)$nYW=k>R1-42ca|+5T8AlBP)$ z_0R(6N+v(u+s_LL&YK4M^ON!R>MjROTjEiC{H2vBN*xBEnwN~tEyC_ym%24}+M z+A1RkGPy!oL;D{=>R8WryEhl|4w6zYolem5BULT z4Uk(@WEuZJs;3Ze@c$Ym*CA;1SSHiWnGY6vxj4w&@`UC=ZO9BAZFv&xoeGq5NHYy7_n*TCc`2$_ zEfDy{iWcH8$i^6^hDVsJw`79F1K?Vwz6YEw0iKq-Iq@1PvRYyM4zI z4EcM7eN&}sI3q3|BJjT<`^z!~dxv8a-oLF*kiiKXxk}<~sBjnv?r?|v4bXFE3qxPv zYJxmpBd8WyOTp#P%7z?-WDiMx&LgNl%#7Ze*=d!^*(_P69=mwpX9>4Qt4ODPHEUK| zFRp+8>6I-v2*BIF*=Chq%tbKs^#8a^^Hgu&Kh4`pc)o<}PGenY2LP3{&VSBCURI!p zQ68(INPJUYj|ECqRQXgfh#QlwZY^C1NqJCz<}UkS_g*B8lOvbQRjB_K?ptxyd?k`5 zYsT95kj5cahbtARk$pYhH}&yzm*g_u*wA<#4LucgZ~5?e=v05$*vXsLg@7Vg z^ofVS7TmAZGFr{|wWw!U4aGe^O&Ck$fGwwG zDFU*OIwtgNmOt4xZ#;)B$rVw8HHsxYZPUq_TILBv#a?xH)PX>!yCc1Jy~-skB2HbD zzgZDpqS9g5GsTJxeKETFs#`x?;X{E~bj@BZ#P@bz0U3pzO@Q}wJlklsV+`jN=e{qk z%rBC(2M7Js#fP*}If8G!a2pamEZz`sk%kXO>W=`&i9Gz)O1N&vxirX;NN6c0-X6`a z2x~1AXF+(YwAshTz~PdWZi3%4EzK9GYtNL>C>$ErDv zbgIPqoJVS?!afEsIGsB5o%*rG8oPjwiixQA@Oc6T8<8s%$-4nYWLT!sf9TEabzM{@ z{NnB$l%S+O^P@H5{=SQA>4{U_{PKdMNnT=c2I7Z@)hbv)%6NoHl0M#(I&n(iQr8MG_zm(Aw#@^i*(sA^swJxU)ak66Lpc(b;smw z+YQbdViQK|ygM7AM`P(4JNjBD9}V}FXs|o+*FHXPqeLmY<#rdnf%c5DnmR;@#ur-O zn--t#XTb6C6TMD?QR+Z$$Vv&YNF~cI0#*pV8>4LyHlhk(6ndn*yEt>&$ zw;!9*Jh1~$L0^LH$VO=)>FW=PJ4ROXjmE9s^>_X(Yp#Q26)!V)c;A=xm+zTpYnBtZ zN_>Rl&-k#;3rU3!uV8~+N#_Y4NQjARAjqs63C&teJkAa-GyBOkWrn8E_7Sa>;zJ&m zFU#+z9BF3#mgC0pgfjjZKvhufJ$<^K6}NLooNa)E)Yk}h%~iMc{4UM@2yPpc1Ss4j zHIO1qCGqq?eT?<}Opa@0Gj{RNgXD+*)Xsmh%c1c88-E843Kl9qJV!;<0-W3$gyWNt zcVdbH5dw{@!<0)JNQQ|-2VD!=gnwS=8QZtni;SSNjJP|Z!XgDD zhO=-_pR&l+0x6+iIYFdCd1daes^=?0Uu*+TIQ?w8BYw2Zpw*X*Pj{Cj>6PYmXSnK8 zGDQEYcQ6U zdu9?TiFYjlW8pEY~mlc+;0NOX9h6b|PDmr9qA7Ekp{xebDp;TIjhuild|=ai$#Hi)6sfatPe&mz{C8 zEIJuIet-Awv;H^f}+)fV;UkH-rSvCGQB8^qZNJbxwn!re19=+!v{> zGb9N4&)*kCM<>BGdZjkrGncU5JYSvKHL;f-fY2yt+0(Z#FSix{NW9kQ zj1iel0(@w0rg1^{T2&y4aIY~4_p6flwC`LwxaLik2jZDaoJDY-$aSH<2SrX0c^siH zqa6Vj>bguaUkI;>TFFfv*1T;DJ0FyTZv{y(X7=TwGEl&u)^Fk~~p!8uQMPd`#tYt|#H!h0Vf- zsL7~R$h>danI}j z#!cTX1futp3Xv$(nftbU`t=|k*CL(xb0_-!kxToA%d?;j{`8I2VN|ELb#J3qwRb6_ zZ*DaCxy<-oqLGjHqQatn_>qd5EpCs-tq`JZhSH;VOmK+Vcq3UBWoR`}UUxKON#3`3 zPcld)#(_}!69;aw zez%13`dh5hcn{&|n7DSRXWU5{go;g3-Kf7tLRrJKa$}h;>jM+)`qBoDXiBuMcYHSX zii!OA`pPwPwLY#!QP}f(?FFc#^a^}^PXs=+!7G^snmx5@VgSq81`1I*CAWzShcFyq z?<2JP`c4hir(s&r=Q)B8c!;GOm7=nO-Mq;^U=2MsVQp;4%|TAdt6Kqu<~0H^1hdCL zYJ0d*SnGZh1(zT!fCMG}zyj7I!L$dHe*nNUnM!{D$zf^Z@?)v}hxt15vQ0*XN{Gr} zK5_eogm}*g5nofIW};y*{*xd{Bxs39IjNl)Hy`!3;7;CVyOVR*w)XsXg=H2%>x=uj zFBa?WXKIx*oEji;ArP|carBQ=f#M&r#NsSlQiZsSz_0b)YVpvtj;z-`q~6rQ=hSO= zZRm^Sq|Kl4N3X?2nt?SY!t!rx2(Awq|0H%^c@kR^Ya;$g1)L<4#9px<;h zM!oBci1k~YEeak%AGg7Wb*y*qQoa<0j9ia22Agg8Xw(;g&lz6y70XdI(pWgpB;asj zzc`LJ6w&$aKayxBFg{GaxUzFl%bn)xF29>&|* z)EY%z#O-@%ffG2oUpyJD+O|O0TGN>e{z=|Shv(niGi7{W5;n%qoUJstKQK-j7)MRN z5jS5P;#!83;R<(N=&cPa#U>nQ;#`75>itHcw@7BuRD9{a89MZvljhn9Tk0+53KEtU(yDM> zBAgyW;@;=no?1Q?8@wQZD19Z*2<6y!N0|eLFB#IRe#@mBoaFc}aSUck#|M_)hw)m4 z{gzZoxwHFk-Q#4d>iYc&$?DP+g5bBP60m+>HHVTWgOe_*6HlPZ7So~6GhBBXTxiRu zQgavlQ8Vm=!-RkN`n1b`zCVQ-FDso|nYjpK2`t|G?>n3Fzo+amZ`l4Sb18e6qVZ@t z4p7Un6qnVCHssdzUYg9JfAyi6t?>a+6)94X^tdB}C0|#5J-fY;>4Y_1P2zt{=V9hPbg}dk;nY^B zFVOdWFPlGcRE>kLVdkz_I^Q%|$2Bl#{z~y|AHe5yC#(2L7KB+dYv}+1Lmhp*8LUr0C6rg zvWGypdgjaR&Dc&}q8-z6;MHYKfVYjabNGBT119bE^xNe8EY8nARV|{DtMHG7@F@Iv zOt0%?r@UdZlDnC;tFCX&O*lpti3F`iw*kF)f)|^M(Nm#X5*I{uRCoa^?%_$f-Kc3} z_@M_4`N@{&C#&tx-VGBD$nPW_-DB$-xPtU409aoF0IqYjaMdE3-eLHBUj9&}&a#H- zJhw( zB*u&2nQDj7NFHlT+RI_q0f=;VxRy^?W8-S482j_#hpJgD-(mofFJXS%vYVxAMXmMX zX^up*?Xo|{Zr32?!Wd=xCK+r)5OeRexl(LEa3^(isr9ZlwnpmL6I66Ye|LyipxUvw zARl5p;q;4H;51m&BrE1WPuhCQKUPKPJXKxVPQcVW>_1KgA%5dGFJb!H!ZVq1T(!L( zETRO!g&h~taOo@?SSc2FAeys#e?}_SO3%5{*e--sit^~s4D~u2PIj__Eh&ieyB9ykI?@ZR@ryD;M^r*m3y{LsW@ zJMobxUuE=%a-Tpeo3T{5kf-@f3lF9e2FmwD&E2JMz(k(%=B1><;v0sZQQm!)l^4KZ zo@V`#j5juKQtqdpace)`*=XVwu{pF^NHE&PQH|bB0xQwvkjzAuven!{Kt#VTzx zeez*4OW}UxFsvuS>Q|r?{v@XtencP!VmA5ZyRk~GJwGzZ-$Wd5*{oeaz%bow=FaMAVnvK!99>BE7<`n?Kh)G`7zm8E$OT#YS zV8Bt{;=0q|pA6B5eby;~xC{M|E=)Du5^1?5$fSw{qG$z&1zTcZ7%nzI39_J4h=NkV zP4zLqLTP?!XA>v2uVREVt0@68u6=vXuhSxOdxNg&EG5-FV_8a{ho`K)s~$%0Nnhpd z_Hr}~2UvkOBqrRmdluf{@2}a5BhZm8EY3>non?tKjxnija6GO%xR;X%3)a#YVW zRQF}ZfDQVH?o?rcY)xUgY0A==1}>2{3OMXN zv6fCu-ZyWjUhWtR(uJ?zH=D>BP;h1m zjMcw)-OB#N+uZj(B4p(Oc7ydYh0J5aDK{H@pz2igkInSoPJAuL(vPJ=KM*js(vClU zyET{`bGmwsOKn;Rvi=yrUR&5Gj>Da;hlTdD1$ntcLeeZeb0B~wL7>Sm!%o~z7KJ{@ zGJ^XuBhD;2b%XqE5@m~j8FeM61ii!;FVRp^QVFvT>kIcUjnB{@#zKehFu6O)xC{%K zpoq_+eY9E#K@;bfs@CqWnz3=`kaNFstvjdJ2z&v$9M3NL$1U5vn}c8>@aorwQPw)e z_M@Lgq#7an(;kG599On@yc}TZ~@tE)4SVGv6Z>Hj5m5kLf+vT-~_x-PRcc3 zIz;}ISKjxqQNPe|cuYMB1g(ILmNHfF*AT;N@7qN7IsVH8ZAX}Smqu~ej=#X{&M|${ zST}y9#BtYk?*YDvnqnt@dyW8hEgT&1(9e>oyHgMGUU^ngGWA6P3R(~(knL@2UnCC; zU$S+=2B|CBB?pmTF&|jW}(t2cIBw@;+IfS1AHoyyBf70kQUXIoN zW>Y^vLKwOHsn4cx`aMEdHmfh32Lna!rNdA?pR-cPaNeOuNon7BEs^1c2xXqOiiq=0 z@}U7)S3^S5wW*M~+a- zn|ySUQ|Gk}tAC=_cMYJ_pi$VeT(C+8zzdXd-1+G^o^!5lUT;<;#rF{89tcx~eSUF} zXVKVUph!|#Jfi)och67ioHZe0fBi`2W-&eWy^~DNICb09;#8$;T%u_phhK8kYNPhk zwR(P6y`(P2eL$L$heF~_+v9v-;a!%Ephn~YL1muizI>YB64_| zbgJx&=!KA~{b^^ve(vA7J}F_Uq@ayQ*&;sJ1+}WYv>^T8P(*0eC-H2s>#Ob3Z9lXr z^kqN>T_b0wpf;qugdD-nO8?h|(k#UpY@(G9)gm6AjY0?fRU|10gsTXB?;W!LIT&5c zoQIVxEMp-gR@U=GY*iMy#01(iOgd~wnkk^agi248WU9Fv&N{U+=^N<%*<8Z9ns&E= zsThdzR((D0b#U4etTJnhOw(-tn`c(*qP>*QlH788HUy~WP%Ek&R*8t;Ohi>2aZ`UY z66Ay3*x?eS7H2~G?upu&C!G!;mZdK|QfApw-VT!{MumP-$e2MjkWP`AsrCIS!d~SJ zv?M~=v0-K@oX7$7G!rOU9FbO0{hrd%a+WV%vpzIzvA%E=5Mz?V9b@_s=LDi$X7zq2 zx+(N^hv_@%!YPh#ClGO<4jaO{83|?dd6nwb-)T^irNqdeKgO5kJAFV5;Iz|_RwHK` zt~mlN+)C(-R_tm_3jxJ7r?ms3f_~Q*h5p(_#@6+8Z$MPxX0s5iFT6K@Z5(83=4G)N zZnU`=zrE<^oBh7Q$qty*Hv7!<1+60Xyw~c25J^wG9WxL@U#!xnWa+?fsz}?d4q*ar zZu0sFRSl`0904EZ#gDRSB+4M41}vyuq0d{1OVO96oEyGQS_5W~5b=1(kV~lvoKC{# zmS1i?PZU#^J7G@j_1Y7x>)K_?*V>y|NjEjg*QN!8nlLM{1YI~E5M!FI+qBZ@hQGa)o=qR+^%&eg^GS7lcjq zn%1QPHa|3{_v>l0gf>rm^e*=Yn{`O0>8DR6&--IIp!(;Xj)x^GOIEJ5d<=FFmBf;C zb>yj(YBmWpO+A^axvpuQt9ge7P2p<@ZiiKNj&^l98V+*giXqH6*Z<_)=T}o1uY>wL z?P{pKeRwZEFdw|FYwCM(mAvWa=~d{NUfB%d_z?pCx3(#N$_7w*T5eX?ndS;EI^h-k zG1F5ytw-C_m+I&$c}zq9023nYwl-G9baqs1PNT4zfyJv(-FzeqRrYUAZRzVe$>s8N z>|QKbcTh1`<@v;LxC}^s)X{GUif%m?VFXj-OF z2(@)+F^g2nZbFxOg@!?_ znSaNU$NC38i?fDR4bJrOF{{#U$nIC{^6 zlXr0VvWE>YL<68p4zOSQ)e)9gysn6pAGqDzX~pCBS&oB@q&v-W+Bn|)fr??oO$H=| zTMCG??JzSW5y$khrKoTgx=$D8eKp1I?P87755dzLKvW zuHhds9`F~vTzJkz{F$&TD4+ct_rnr(oQGocvzYD-ks+_ns9WZ)flPGZU6_CC%ZQD< zad%#&r%g>4>rMi8y47f&c0V|-93%GI;w)S~66UaZ-Cdy@9R`FdEc8I@rQ?ucgH{e@cCFxbP)5IW3_BuiLAFlND2iCHdq)%67~8y zJJ{v=X|alk#!_s%;#jACrpb?22TE}2I(LgiV0t{De{E}}j`P=aEV>Y!FG{jjb_Y!#*WP%HV-M&UK zmF_QX;`L@f z)MV0TH2l>;8X+Q&?S$&2p?I@;hj6i$S2pxyneK9}$kk0t&H`KqQ)NN^LVY5a)M6U{9DIWZRk z%vPZRNPp}N#CUIGAwRgiC;`YyGelfA$_B^ci<+%m={O~YtjL8VoDFQ3eFM2wo%(BsI;k@e4MAi+4Te(bhQk7w+V~jSjPAK&Nb>3`J0%bLMw333Xy- z5~{#0tRs8K$Imxu*u*Kq|7tG18YNz?OXerRtSfz~9j8T6qzs9_8lAlH#yu z|A}Dv--6siqtq$=7cr&0-N+)MWgHR$8vgv03Cn8i#gVjrI4@|HjW~y50Q;98`|Iy^ zAI&gdIxKW&jHr{KBlhOHgG}uLFO1p~si;D!K7LTyfj9~yq`&)RdgN0G4(#{Pq1D4n ze-LYfcrYww{3+7f$%XLFlzo0FbHu`j4RmKm6e&efW)L&)x>VM{Nx9SX&P5yxB`U!(sw zK4^N9vV1sW)X&oKG*T}Ba_m)6(w-hjK$_H-paSfI-KAt4#XrehGUnZfqb@Zg){02s zaG}c@R5UR=V-dVduz25VDOP4)}0i z{5Qe;vy5-citLe@VwaIO63!W@s&h9AABSo**~z?q@RNV`ymROZY4G~l4blg1l6Q8O z?_xsWJe=N`ij;)FA=K}`D5x{P|CvJ#u;X%<5dt6@s~ zz7%r#Zdh(g9sc}6?6<$=XQr9K!z6E5s$sJUlb#=^W+@iVPouN4B8<2NHSJ zw)$hz%?|sWN?A{&2B6u>j3&O4PXvNNng+G$D24zPlB-N@YOw6$R$c~KDXr8}c$#9P$v zo)e=WouFB$k?0=q2L#p1>>(3s&CGzPqrOk)c3PM~?KdEDDG}k0jfPwT{OGPmcv$#1 z+cZGZg-V;z)cZT0VPd^ z%)%lbjlQX)rg*4G>iKw+P~A{qs1e*{^WJLP4$uu)zUlVIyoIbJ?8#umH@~0|Q>N0> z3s)&5cw?MNmuY#`)*NXPoT+5F^O#iT5BwK+d#?ED1r@$g1hL$=%SI;2)3pXRTF)hSA1q1D&5)FGcbvpiDgsw-rbuf*hB>orUgDF9IIvHpGE0= zSo&7mBmM}-d&Y-0s!^e%iI$5o@%M1hH_!kTLsMQhHBXcixXI)NZ1b3RsTV*j*4G*O zUsG6@hJ3rvEGq;b#43g}{zgn$x?Lp*2Zv8Oi(5bkmAW%7Ye;52S))m1aVEWO+b%xh zWI#XWp#NBmN@5E{TE`L!3f!H^z3YCHANcxn(jqhls!@rrgQ~=EStx#L6|UD~>m>6U zg5>RmHki}UvInHXP%5v0Poz-cVamJy=+-z?87l8?CAagkdZn3ncgH?@G2?hC7A#!R z1e3tI=oY~{{Uf?mDt(!u3z;2{AQ(dkg1=$9lzbp2IyQSMj|AgPYtUnz8U*buvQG;u4Gc_uluT&!3Q+veGKp2jFAM(2;U6=NptWl z@j`Q7k?I4uKs-7>KbW259TOQkmYe0*iN~@P<~EQ+b$#kx)H`|JT6`TE*2A*X5FWJM z#ZGAfK;AzN2usM{MT2LYM$j7<{71({jR6cC4I(_KYE_`XXA!; z`>MQ}F>iBEvJ~va&o9mu9BruN=}HLx`})8mPDg2?I)lUc;mgrRPE#!zT}d;;+yAlvM6s5p=+Smx zewU^M!`>_}r=?p>7oO`SZt}K`Z&GAbyVhy#Na5+Z!jIcX;KPTi;)-aai~LF%PtXG9KymP~YU+dzn`>IP(B&Xs@2HLU4SL+iJY1 z_HAe_I+WPl^M1M5;oF?b47!6qz~02JU+VqVn+N=8xn!Wb?w9mzj)a;avDRTjEM&%l z4RiHKOyhf)>8~aS%?kItuOd4%8g`{A$d|W|1{s(9o_ovGYfED^bTXn%J1CU?Hq)VW z27DUu!gv4=wF~MW=cuK=PB*MWWIyN7wKiv-1VEHdmNz76; zKZ=7w325)QT%Oh2_cMYi3+N3}8(CFxj~}QVwxrb55`jcg(*FdZ)NEU}(8Po9$hQ(w zBxQWvn*+FT9wbMDtN*YcBaz(l>FHM2`s0mHz7 zShMXwTe)x&N$0Pf{x)g$*#)L5tj1tfIQ)E)S#DIcMKK%hg$fk{K@1XnH=4zq^Uwc` z>p->P)#98E&p1=lS}r9nl9?0V_aF3MJbv_#Sa>u4l8J-W%1nPuU;Y+hId{OmP^k2? zMD>%i5L&{gt+u&hxW=R;W@czEurD2(O_Q&?!B%s3-PwEo2AhGl7FMnn z3Mf>n^8t_*PB*=NbtV&`GMwYEs1Yn6bkozIJb;-ZMDi7A?VT%`E>}^KvdVn9LTFgA zo({w`(AeSOLjZCq%h#TV;YtvdDWmG;j`NIG;)`Tm%&8f5`e175?%ndxuSK|+1Lbs~F<9nNuQcl{dA`wN28Z_Hb*6u}uKR*g1U=Pen0 zDgIf-&Opyoxo#h54Do|;U+i`#cfCBY%G13UY%5%HRUHccW?pqGnc5dt#GthA!Hnhh zVE|XA$&8ESm)uN+EvlDYnGLyqpzN%U51oY$_hG(S^EBEf3TN*S?+W(ay?A`Yo!1Iv zgoj_{o@vIc*3xEGoWy@#&Kf{Gi41`CwQ#vTJo{Uw((lo?Vi5vaJZ;uvu4+2Rk2kfG zoC~Ik3o)(g>vDq;o&xO+6e%xK`{W-n>X4?ws}A{r4r$Z>amuW}!(Z9B9 zKT;Z*8Sh0{C78;G)^Sr?Cq}gLZ)MMqvd=#)huaR}zQhE?45Y9DsrM%$1UibQYS(^4 z$c}N2V2R3)xe7?V4fLd#j_#i$hbVadE}3?Uti6qOV+KpCrfzeBE{9X+S;hjU6iI!` z%1_T*fG8mfINZia5^QO?6l19qia1Tlq(D*#IlNC&VAaX&@=jadq@?V^OO86M8R0n+ zF^$h@eoAJlVQ4%Ha}hW#f$MUHESetMxN?wuj_XCn-f%`XS#mI(2NZ=!!WfA6tBU3bQWwJHP3SJ=mxpfhEEq0}ESl4m>j>yBKaoaVevcg2IopiZeC zV-Ci4YDQ7A3-z%8j##hSJ5kL{x261eLqWw*T(Dc6&+B)GzGwC%+x%_Bfj0F@ zBYKfM_sMu?6#symLhSWY%$NN5{I9cWk5UAgq&zsh`(=Z*xM5VUW;%b^f@=ax)86J! zOuWsOi0V@=69T@j3nCfDZV4_ZxTLWe-#0nwHtP?_Kkg}*z$fPZD|7Ji{u@AP44t(Y zIP!aICt3Nv+{JWlzVPy=ftV37)3}SA^o4ECe3Ch~4JEY(Iwr4!UFsfa>ZqCPkg8kn;9Swk35jE-y+y1-`oZQWu*aaj;k} z*MNTfAeoK<^OR@+X;NaSdkQWEc#buj#);0RV2acX%m;EaHLv;hZ782RAhEH`^jI(J z97@j|H6~}&#ITJ$sj&_qt7r2#NBv8_o+z^8+i&uv<5{Y`>lhP#5ZKEscm(=0iJmCW zV9p(+^w#*?0paE1+q!?4LabEm(G3QsKAvds`r9j)T!mgA+w5Pa*1+4Xqq3%ru9;)a zfSB7@O%wU7pJpHpW>KrRoae7elg=fc4Td}0M9n+{3O5p5XC@kRva~U0%yjI^bgv*9jjt9bNbRlFVU(wuXv~ZDQwZ zR+^8kHU;!nv520#6kt}pcCG=VRLmGO0D)NRYdI+gm~np~e@#f2UZuOA<~-WvyKS-$ z^BkbbfuLgmlV!=GgH2t|_B{1~7Y_=T=~P8N~}{1uGZ!t$vch0r`)+ITX) zD?wAoLdC6=j`fPgjFoK@deFv0V9>lSJ}eJR zlAj6JxGwoS&0Q7``$>JFZ<4#lJ-ObQyf@}&WAvVJ=-k`y_bWNy2{hHGB-L%UFGmTL z1DOe!R~@1wjbX$1szW|CI^=t>#@E08*I^24%=*1pN6YU8W5OENVDd2+pS8ef{e{xB7d3_wQVN@e99sWXyXV(v=^le4^kk|G5%ZR&uJHNGpQzu4qL9aLhRV z+itE@3mvI7;3@`*bV%@DC_>_5c8+IhBj$MkM7!fmG?iF{iG;P&zFka>~loqM)Ig~=ooad)L#+Qs@xEGyvM@L-+EMtm#xhqoIF+`(4`aRGy!u>10 zZ>LJK*>UbEe;)C`1!yz^H#wK7!M&8;M&eVXj}3CBM0NZOfsJWQ`Aq7KYD_Vt(6VP- z@$t)9`;Lh!pw*E^PZUFr)5pwc$}wPz-E(!CczF*{(fd+J;~&PqD_^<-RZ_xgKlkRO z9>=sq69<628Nk`OH&Z5+rmv{jfVe9=wB17hQOs4>@@+a?2ND5=>J#(Q|JuRp&&7Pk zpNp`*U`2ZG17_}eV=RqDj6?nU7Aq6r4pe388DB5g1~3}iB0HA=0doVmNzGSc1UlDp z7n7-+fuWN1?g7%;dc(xDdj5v0XmkEQnBj}Q*tRL42zS6^QK7>GVTJO6T6ixL z8egsnYH1cN;3!~s(O)G7ZjsmT=giR+b)Ipz0Z3h{xVhLy09&h#nd4&^x2++{zvRP3 zHclLf;H3JnXzEFm5o3q#%m=G6I8=AzZun;I%#mu=Z%*-M@4PR?+_aB{U7N_AkWj!& zepZzP)!xx-Pu5`!+73{F7wCKQ$L7hZa#0L$eTTs!2V(2WXLi-`dcH1IN$<$wSvgzp zrz3VOhSI#>PQvXHGB-PYuif{?<{HD*9Lkq9f6?lH!d6bMy6P#7M}Ci`^eKsYEPrX3 zGM%pr4031dYu0?5Apc?lE&9ch;L)XG!cDdV9sk$TGIifX_?kPp5UjOt3FNRs0HKAU zovS=sKP7{_k~kuz#Qmrj_fWoW+C z)^4#gS?i~jpp%X!n<(|P*~knVi|rTGKx_RcneyImFD7_`XUJJ}rS@da@VcV4`8T&w z3~ayZkU)F0<5h=znsmrFzxCH_ywj`ZJnPT8K_nBi41MuSUs!$l%U`h}ZX3?7S?!RBOc~%yfW|#Hmd*$x@@yqC*AOE%=eaDgi zTfRw^C(5W~z4`a#gd7k#-G7@IBlZ9T!il%c4dgWTf@0`cvKQsHm;w@6lv8F~iY19L zAcFW>vf(FB0sslKcKSDbckjtyjE{#VVCu-X4-^W@bC*ekVvBJr3UE%Fm|Bg5S(G0I z`$!mH#TNDqLV3x1mjcQEhj0!o4A4tJySJi#`O(SjipAo@{L$0uQJZcG5RtY3$?T%c zQJFs|NrL!-Et*5PJ)^TK$BgB1>k|FeXP$Fn^4rQww-L2ACFgGr%^OM}6aoJac!&m?=o9+r#lAW-N0nVixn%^Cly;ToDM#-~2oQLd{O6aEDod%FJ)2ID(0 zAxC}=VcUnC%y0O*m9#n_ras0yb8BE&52;PPVx$202{2HP6nZBYoFoa}=7Wdj>r|9= zz>MOHIhyo3{jUFp#rCw*o{}{m9+}#AfZ66vyl*TX01QMHNgeCk)osMxfGr-$;|?GmWWgtPM{0dhZa&;Dlwec~^i=_D&cmBv*D2-X9hl%H$eP=u5$pHs?06U$0kY81KzgF@g z1>iO*1^3O)mE-Xuu-k2STp07EFNf?PbnXfA0vom*a-V?5Sc}6xpOn;Ppe@!RMFRK$ zb$1wo-t|DKXUgqB`dEuG?GZN#@Pat1c88&lX_HV2XjGrc565x1GcnyZ@F7r86zk3| z9ePbV17+F~Q==`r&++Anex(2|n2Jm!nI=nXQDj~$QBiC+jzG%{yTxpk{XU_25@C13 z)O9jLononbM~dDv2;NMz@6_{(135xXsh5F>cEps^CBHn+n@HTE8=G)rN}>RPhY}Z0 zru+QKVhpu$T?AvMm6#pZ?#Aa2AoBDzMrb*~Lm$TArIdZ1Qo0?}r{Ddr{x9G~O(@28 z{-cUtn1!lId3R^Nc>YXr%>0;~X6C~9=TH*9^ClpjiPRls%YPK1PyorIuGDcRLuT$J z5*aVCu)zGr?&XUEmFbmWl<$pi!67NGXJ)%ute2fhPD-WY@NX#*rL zc50QtUaZovc39xEzKaE}nNKK}o5@pB7y2Ne=DX^3={UOyObGDHUzRB}2adp`c9)R3 z^ctBnGwbGaTCTWKuJoJ&p6Z9&+b@}u7`puX77Eoo)8F3H`ZPJT+`R4e*rSd1y=S&3 zNP@4)JNf%=oVWWmV={yR|icPUhFa zTnNlw@^KAt*GWo#eiI0wPcz$>VE5VlEXB)OU9W+<2c339sCM=&YR_Hz!IhJ+o9|mD z=OXbAz(_~6#iL#8??BkPB;F<91)b{ub~<3!>@PTBNo`_79D@c7 zZI9S9t`v{@K$wMoiS-ukJ8d*Cb9V`7SG4mqYm+2o0-in~Q%0ots~mfK>wIC+19e14 zw46G>kK#X?Go6xA*%Yv1{C3#b#yz&Me2)#&bxF~+pe;-5tP@x|iKIv*A{JsLh6p{vxVoD)(A04g_)rHAumuadw2rEp0hbYE-4Dl84unw?O);o!c zi|&L=^o4${0odHrm=pV~xq@l&=4U&#{HqoQsoDh8)GHum+zKdq0OYGfr-|%5uQ7d? z(;G6`EK9Zx#^&C=Oyq8z`WBPiIn2)z92a?6>WjU;D}UJrxOi$_nEP!II>+>+&Lt6# z-R$VAB4nriYIQU}CN+neFQ#55e)G1O-;XQcp`eIEY}*d-X#*qDxhUbS4a>dx5<^~U zqkfK$t@@F0`bwQ_a$-f7R3(k7F;$n?!Ti1^7v4ax=8ZL8mvY;f+=T*uo;uo$S$40V zuiMx(PS)r3JYOBW!;1DiexrU5Sr*JuA5WBeV{HE3N&+6c7pEPtDmPsg%PbB>YzOR~ znILbpGe5M;p3fwKRZ`*;Kw1*=l5Fo=@7BQk)Il>&{yv)&&AM%Q8f%w1*O83leiG}& zL|T;jeSW2)U+uX7A?e!9vpET;(=4p-nEu=>>WvghXT-+r6+wKGLvZE1=aK?XP*CG3v#=aY>Zf8<4nEb`GJ`mxF<2JUK1(UKQJr|8rN%J)F&mDr-v zE)S}BQMic+{{V`dYuh0Q1aB#wxPr=6%m~Zi@fnnl-G7W0MO|>kL{iqi zoa5E$VjMPT?De$+;k7kCwI^dyPPj8axC?L@rYa({^mv`|dBRG@(X0Wh*$m|1ZV)o# zPLf`|QsBYS{LQ~E_IC$7;{z#C=35G`^ISoBET)L#T465K7e}XjOf&Vt_yhWEqYvBQ zjIzU~l^8n%`XuzWxC479%5R%F8>83#&)RXaW=h91DSGN_N4Rz7t(#d3sda0C_Vn5u z`u!>}r+GIfwYDJqM`JuU=F*bV#5DmG=J7T_Ik8s?K5113C;|tWgX{a+bHH52V(pxD zI)#~_ym+}N)-QSjMyL}q>_88EZZ{nT7#pqcmw*L~HNdkq z-e+yu_^xr82z5V8j@>3<2V@LW?PozTxf^t9#hCkyLuU0@`huRyC)ehwjo}R$^c3i5 z!!!(;MCt(3fhS7(nvKs$D@H6my5p2=i zDVjb&*c2_{_j(vs^CKGEc)TO454%NnbbV=w+E|~os}nS0`-|j%)giAs1T5O+Pb>8@oGurmNbNk&-?jAZ(M!xi?a!xbVme7c%pPlVIm7_*3;+^GUMZv zMOuBFJAcGIReDQ_1XwzWVjTJbff9wDV)HEWEn%0*hl~a~{KvvR04z`ZO-dP&PM;GC z$b+6!V8%$#1lGehoyplAn_>o{5)eg3$^`3o0-R6{ChQ%hl`qg8Ah(nlFrDttIZmmF z$0XqFM9Ct;5;jtBA53Q{i2jqnjboKwOCKkusrEMl)=gPx`mwXUEXwd#xl4gGBA9+u`OZlYdS+ zZ)5PocPG)f7l8Je!i}Y=&wcB90B-+fzk3t`yel%-#JiNfArP#B;~$CkReR$D40+y~ zRx62e%F~_N=iP*GY=P-HM{4!V{H09YI=G#;*XR+p0b;q zZWN&BwkS#?(P$Peyv4A+ZB9@q1$x{BNXiK}$tJEn)xG0p)8s1TaF-}hu_!B>+YiV~>*E@y>)DbCA@8~$OKn9TPzdkp_uDRrM zrxccQQs1lnS3RF%RCE#jDiuWIq_p?%| zmT;0fBxnATWe0dNQ3t&9CyUjq-|}Ofq_pmOuKnit=II-Ptgtk_Q%~oQx)YWDHj}Nt z^X=SwZ*_cAkdI2=I~J^DpSo&iqQynEl?(Ps%gvgG`7=-|vjkcLD15 zTQ{z4E4TJH7e z-Rqq|`I9jkknP!3C7`^;g68f}3zHG0aS8aWPT!t!EN~}4we+R5LQKVXcVApxeGtgD z(G>LbtdC~R5umd{^X^js57-dIwkNbx6x@LzwUvt z7z>ieWOEPjF>@}zrYlRroLikF0^Fk$MFXu#COb!r`WU&M9N3060k_A?}5q|(^+uH8Yp<+6Li%MT;224>bvgf6p)#$ z0ZN+o0^B~hzvH)Blp~~F7pt_6cE&u7IXy)(3Z_K>M2uGS9p&GHGZz;@T?FmkwP#VW ziT|AA>yys0tzG%~bp+DXK8=_Y_atZyz}Bt>aE<>Run=>Yg6x`xw)7%Y7~0#@DV1$` z6_qmvV=K)^{-7~CW70Nk&jdJ_F0{F7&x_TK=gw;0j=BSz}06axTRS?L*eI5Kw|#rTC+<3 zte(7lLhF5^ z$$acOhO1uO@ars*Goj+|q)`3g_gHsk|5H9S>UwC-HAVnX^Ri>_Vwpwdz)Jb1kq5^A zIl!KfQIpp4&Kbk`F;~AfURfZvZN5hMTEpi1By+Y-wspMr6nQw&`>}D&WSf*tCXb4B zNcE^2c3T^sDWZItn^j4J{QeVt9rCI}K7Bf*NZ9~gffPps%HQ#K{Z3ZZ z&#peOk@>xUpLtHcO>WLvRouk*K$pMsr+?p1ul}n){ik18zwkikMB5Dvmgd0h6V3glzy~9L5QvUKj_|PPpT$V(qxx`g8$S*9jqtCvewtmxYQy zFlL7j2p+;Gsm(7roIHU@IrWJSn6pYp%Xt1chco@46q0=%7T+1G&g2^17Ap1!!Biv~ z!9=*t5k!RAfzQX7Hru9pnjjJF%2~gR@DJ*E4bY7Pvq_W_^eBC8>3!Zf4AC`Vy9Y3n~X z(Qtj8X)*sS|LaI0T~`;nhF`&spJjbV@ytZDgWq;c5v7yqbjH}(vZZhds8wQLCqG*3 z>KTJmUOY-YNBm&K!f+Ws?aV*2R63=jne%w-pD|te>3^{}l>@~xpq?pukMS)c^c^3~ zz`~uD+aTKu_TPN#E+9SP%7F^FyjHN-Z&p&Xdb&wn42I z)jH9Yo*Vmi&Sr8x7dtn*%L*R8p7KIe-STvc~xcg{g%*_C}Z z=P^Hjb4-r!^EKX?kIf(31V60@Z4R8|_tfX5t(aXuFtf?GG1H>;vFCFd=xuzOuO*9( z8r&99ZGHqqFP+R1+Y>mgKlFRi;;I6V2Y_wc{Jc@`;UA4{;DTk|Gt5_v&jny=lTibj z^J~oNm|$&8-eevov;vo%g_{pw*IuypTY%)med0>+(rgU)hh1#wW(dfSNrMDTWu_O) z>-kvk+U(ssNc4LjeG^$|Rt4Zaze?w0SDzFaza?)b51?_Yw7%9cqOokf%TSj>rkr|v z_IxuBU@7`lUG+um>e>3wrJ*@$!p`_yPmWFR%I(85vP`UFqMdHB*0&#-e`gfk%}Y9* zD_|!^a5fXnqHps}GmhIUpo~n&4|oam_@)||qg$H|t}Yf2fiK#hZ0k(kk*UcZ8{0A6 zXjef;0r6>Hew0Z^?a`yn-eny1#iZo{4llA8G*X~ft#O^;8bFhdvPq7I*Pu={v5`EH zIRy%Bptu{Gy#c{lWX$zW>&Q&osS_ol*SeWsA87OV)CC>``K=frlKfoDfOby#~P#2UEE*JY$M;rh(~C_zLb5F8XaArnD1KI=Z~I4UyJ zzXCDdcr+kHv6kATBff((*}WIDB?{C4%;OR{vx6=oFr}K35Bf9&Or#W6ndA4Aap`80 zotJxx>Cp325N*(XH_>T<%?0(0vhchoASaVmmfNX6zn=p^cEYUX5MGJ0jYY~_TTZfo z%fbRIyY=93{m|~ff9D>jw-cz?s~3=$AWtFZkC)^36}IM{0!{nkgE{w=*5q*k>k%-KkJ?` zBj%T;q|8b!ax%9M8$N{0aC!7SVQ!8n^r--Tgqv8gpa!lB6>SmwcC(fLbHe_cmR_yaEmR zneJ^EN^st4f;(%WdI!|Z%QhfD&P4^!p7#I@<*VC5JOCmi1N^yc5CSdgsvo_HAD}uI z@Y3&048dmbZ3uS=l_=Gyv|;fqZ`t0u)92tPRf?x&wda5?1f)QycW;Z9aRrO=~C% zhIztowp^nd^JY%iiRmy$OZD_VQ0-NRyy}qF=%-DGEXnZAda^n_RQ}PuoVDXKPNsGI zWkGtA%s$Z23bEeO^=F&c_M8I@Ex3s*aF+FzP1EQQ>+Iu{MLT?)JAcGIlaLsII2UtI ziFN?@wSb0vm`Ypm{o}?+RBaiiC&hP)JxJWdL=am~`G_%B#1t|!bH2Bd+m@=n1++iWt`9oqwCa}VD zCVv?QVAJy`+c(!=@Q_T(fmHQrSK_a2V@07I1t17Hth3$#r1uJ4L!?3(<;wt$n) zH@7T0X6*69qqv{W-=NskDF(zs3v6Y^M+nF%uXuv9pWbv@m97IoauIAEa`g8(0R_7L0x{^?sCk<-p{;N#B2ST=$eS~@goeh8H*~YuDZ=!S-?;m zxo2}DursMQu-O-zzO}j3eC`;s%HDj*1bn*JS|GO#$K#rxBLJM=ToJ7|1@ZX%&O0w{ zjP#jVO>P(FQw}ZVIc*d2szY9N$fr?#?mYwXN|aK!AFV7&Bfrz{Es1l{s6N=xz+EBRqn zGG$Z}U>LfZIkdOa)xgX^`Ni$9Qz@XOpesq^ zE8EF}5{tk*5hO*0mNul$DF4(xu)v%!rs13N>ScnH4#Bfy;8rU>Eh#qd$b>qPs$Nk( zIufam+kh&MFKJW^2n9Aqj!YwsT8f{+V^Wy7c!4z9f>kJuO8$QvLM&D>6HAf0d+nPj zG`mnL|7Ro3KoH z6SyV%O)0uFKd_G9s(&bU)qFLAZq`Sd@~ z6N50OEMHxiuR8xOseT?mH}KDRZ3n=qAwakWR(Cmz+u8T-qWm)HOcs6Mc@yAH(N!Ok zzVm)d8M79lSsIExpRlFGh^dqDd!{7z?fUgt&&rII=`{bOnb3g16o?{Fs9Venb&WO7 zxfLr^&byeTYCj2SV;%KJ=An`zZ%Q9BPctq(hZ*Y;+gEclQJ46(6cUX^z+`WXDjhFY ziD6o|pi}VD0F_kt%6K1vl8(3AcaJvL59K)Q+}%q7H5i!EfaG^IzIp?q%nK&Ga_~8% z%$)ta6&OO@{j5Bn;u>QXE(|Ui< z#%r6eA~LUUyc;k-wAL$tRyhGPr8f_z1e}Ugc4;}E0yi;3B~)%M6y#B|-CQCL>eW~l zNO6`P=q=`}#MB$(ejpdx&}~Gkm(%fKrY8AeUf1^0@03(IsJ$z=!aOaN$v8MmO|v@y zzBXi&a8%GvC)PIaN)=OTmV^18597!$&tJ~Mtr^;4Y-4ScI;Fok=!Z$t?eC}7DxfvN zLi#QyuR3-No$a65Em|CKCedEj6uG1?PXKK5CR5I}dG!w1tQTifN?x^b(7CfA9;S_K z3dB9wu#uLlk8G^opphT-{hOIz1r3o^%|GK+`!kz2FEfoK$Ij+%Chny)KBQ?rhJf0z z3+gh=vGw0L-rX@x+mz7&Bd1N0BobMwuWUxH$j%hv-aAcIYsEUEBVKh#vexLm>JYu~ z>CqvXRCE2BO?)!n5=={{_xr7XS%q3>vpOx<0N#p(IM{s zIAu3_`{UgCL-#Dxv7u0-1VTdD_d7l|yUY#o`T-qDI8%-(_>P1s?FV|twEzlX+P|Z; zB3TEP9ew5xPXbQb)X(l&^y*b1bQIZ`igZ{v%KX$aW4>aA#r zZgX4GhZ0do3S`Ulg|^X0DNsikQ6@R3OA9;KPak6m z+wE2Yy{Nhg1c?C}h5#_U7eRV0mtH9kO4yp9p6E39-j|++a-1WFmMKO@nohLm*~BV^ zMD;C?otjR4i}Vdd#im{Z%z@pdh!qvJx6@D0{M+8}i@YhrHXp%fCagoDfD1YXDAXz7 z=A)EO=_^VmykR~cNAUt^S`8F^|+gOuEDj=9oA~WktePdLgy z^-bwxVz^y%JBnB$W1Er11nLJNbOgRr{DEKHZuI~_{7^3d#GJ7l(5+vZ-_058yHqdF z=HCFsHYM=vjR268e_*P4J!bX%N?kuGLsID0?Ijbfep$|h4ZL||K&`oIj?Bi;SXE*! zt3#&h#XM2{$Pq3H0n10=;3^ZY_9ic4&DxvU=PbT){AXMDEB)HM83tCJf*hqix+#L( z*j_NzZ{>sQII~7K)Av5M&zvu?C2&?^;b)tU8`0Leb`&d7$T(ULKARLfACzP7vikh2;ZBb+-*T;(S=X%A ze}c<8qjx&O^qMtco=G;NM#h6|h_x+pH?X}H?2-Rp=h7ZTX@iUUwhd0!8FlxwL($Q% z^Pc8Hb|zp3|+;As@HAXsM5T``>uqusC*}`DV<~N8{*E`D^r^K+4A} zxp%U4?yS{P43ulBW6HJ<{+54fOK_|)Y0>@XoRJeL?yF=9dq_!$YQ2B=jXBCAf1#3q z##Bv*5KJkz5O9oHzwh~5r9wVC+2j*tnN1Ub0m?eNfQd{;fFC6oLv~}gp0bLydB9{O zyh_o~&U^jl^PWx^6@i(mD94@xBG~Z~S`=(f$|?0kW;An*#Iw4VoHy~C<9CxFUzyC9 z$>Iy4z9alI_2j1#BjSlzreDTfxL(_eN{wM^k`#42=jBo;DclY7B8;WZ-l^~BC@W7m zb^faQ=Wtzu%ovG|mI{20?;@5lzoQM)@Ju|$^roFm1!wR>tj_L;oYJ5%rX9DCQox(b}eI%P5q zFb!jwUxUpCM)kZrkV5^?`~xYjn43c?-!JW~Vjhi`u_?VtK7RQ%O*FD0H>9garoA)p zTHQNqbrSeGXLkYlOS>O2HCN2LF|*Bs>sTNv^k7lP%1j;AwT;Odqk497#T-MXF1a#H zIvwLM=0|mZ>u5K%p?EWY8E11%G9Giq3^ML@s`y1CmL_ z3cBOB*4Ejy*LT0?+?8wr#@?adNk*SFRInGzuh$jrUU5OIw2>%XDhhOna^dsGBx?A#?j^HBNAq zehloY+<=$BefcjlM}|Z@6(aeNIkO;=&9nJ!E#4yk1{S2_gm32FzOPv5GOI&A|X!NvD&k zbNraK);jB+S#-u{c*!~S#2myZ)b^(*Z|a=x*5t@F^4%JU70efMctOv~_w)F2RAOiJ z=5A87^oiNMIo-T0cj<2br7`E5hUC9?C)<|l>qqZ+)giAsqp=4|Mb&8&@Z;?WWHTNZ-6T&X?srQ(R^=Jwq=9wkVs~())}+>i42mcXceqm2$15 zdlu5P4z)w&my_fF-2r=+iHAUrJ-h%Z@R)zu6Z#vg;eBfg>l8DAJpyyQDnM3TBFUtwY3~*##PKIZ48~-k!1u8CBt4xtQ=H>hY zNAl~pGbND%FWt;IxEC?WXY3TK1oSL<#>%!&A?VvmCXoZ>`jp>SM@SLK*T7Ifb{yCZ zU3>Qga7lj0$vk#Vq+F()(%b}0rjK2@P|^9{1tck_@j0WY^j+=TihMp6K%+mw>D8Sh zye3I;<3;%uH5<4IE@aW;S*ou3h)>%tropVuAwBlu4D7C>>5QdLa7TV)fe~%??k$D# zW=y8ukrI?rW|=EC7RKxH_$v-){v2@j`RS9bpqBADo1K>lQM=8NjkZ2hxFwh@nmZ@h zl04U^OUaCI{T?^QnKHU3of*LQ4G%mrh4!@n~Bx(;C9WeNk9GOw2iynuo7 z{H=iI)7JXH0GFR}Qt<#Cle(jqYTvjC=%m}gKG0l5Wx)$Enh#P4?PDkhoGp>AcbwnYbUE%X`46KLE-HIVC4pqc@r#Cv&v(qVMi7 zbOR#>`FmsQ+gwz~0mT6i;{!ec4Avo*^Tt?p8b=$8qT%y}oYP{gpUSy>a!lGK6qYOm zGuC)9XZw!mYO46$9PJgHixva0U2$%z6M312ArC z&J9r!$N&I907*naRJwoWH{8AEKQWU@Ta z9rHKYVrlzt8!TI_NCRs$Y;pC$XUWK9Uef4qWbeX0ooex;O5eRNmf|N@UiSV3)E71E zd(L%T(l%^pjsZ{>cEF^gjXJCF4BS}y!{D{UJe1pMgf@Yd*{X!CoVS0N(m0+U{ltkL28c3Uuksfvg<9lcO zp0L8`%nyof2mB3dkm)Cn{(N8(l!W<6M*qzOyYue|@El^qD5LUc1@xLsi-Y&V7-dMC zlovjqXjH6Pj6%w(QhJDz7k6?+5vDV<_}Lw3=fw%#7*HsW%+Q(CHl@kXjv|Bd?^#kw z)QjpDU@n!0{CN2Z4FD$4FBHh|fjO*)%7D6~BkJ}ggk}25Ir|9!&g{6xcq~3Y7!l*N zrl>jKbIPu<90o44AZPGt&*J~nb>oUxpn=5}OSUN*+8ir@BgK66 z#>N68xD~A$m0lzw!*Xx1K)M1o{T3ft0aM6f?FdCfn!%7AfuKyzavU#-OwwHk5wrzh($+y<_cla4zXXP*jSs()&`xg>v7eRiqQgykauw{I*49P1}zn{Vx& z%&0Cg!%sF=$)y7mc>XZE{a0-aV&g(6U8HpwvVc}W1Z#5T&Ka=vSLe7ES=+ncy=x=0 z)bD^*?3wTM;{-pj4rH=@x&><_>9yzw_?U8fu8mI{NApSB=U6pswv$t4r>-6apndjp zUodVyFQ27X_SQB(cWtJIb?YhSvH4f-x>8bi;>p^&%sg7zs7FHTS^w?KyX!lQn07(9 z0KCco?$7#rgK53O&bdlIwE?3-n1=m2bT4RbX)yYKejeYpK>@_=UB~olQleyadNBD8n3Tv%ay*44X=&Ls}6b9A)h84a(8!F zee)ZO6{eJ7f9k*ZQ`RNRj5&QlwB)Lk&-al`q9}cr9;JI(E)xXLa0g(ty8Q|_kPzPp zr$vX%g7~5T{KQZE#Okm7mA~>spZwt0zI$IjF>tp;2DXzYBW9Njy|(SQpf`o|_B$a| zlx7O-NGRuXM}NrMN@-o&@v=XcK4Cxr_UkzSh!x6|`2-|fd)Ag;M|V;4kJ<@~;!Ee`=k^SkEyswdi_dyrkz$V0z&2&3sD}E5&_-bqga(^$V9#Ha zxB!SicfUJCA?`7pZ|}b)VzuM4Coh+Wc`R3D^2a_b)e7rY)rMj4F)U4#e`&gwk z8{i<T_Vl>fSq^F=W>k;YI}UVI9Eex)!U5XKn!PwPN{l5iHHhDut+Yv{!(=h{?T0 zdtS%Rs;<7t!M~kYqaX0-XXmySQQRpDbz;uwHKYEEi))^I#58-=y})=o+TDKfgUko2 z$lxw(;@etp#;uR7$@q(grDZ~yJ9 zU;4$rN^e>r0W}LI`BN_2nDr!JtbV?*XPeNp<7~>Z(phjt)E@3`R=?|a{a$(sE`cYW zSwqqxzrOs;&-~2l7k=Rv?5&csKPU&A^}c&w*8lCF`*Vx*egDbF`1v3Fi9fOWTmP1? ztp3m+`WHuVzI*q?K^Pz*IJS14nHMYLWSHQmAc!^p0$c5(on=7)1T+#xovtt@4d1kX zFE}E$q7s@f2jya5C>7mQij6ZxQHeQPSU=xto7XfQ-B0)fCKpP$ zD{IdHJNM=opV{XT(-lyf#MPdi0(*|psJlHsaFjpflR5_27nZPblFtyMQJ~C#Q_nBy z?-Cf|UA0lY>WiaP6=$GjCo*z#>)qJ`fx+flK`AAPTy^+)ts7>+BC}9p8ynvfpyDht zpS{)pCH@5uFp2Rj#F^+*e^ZSGiS{sMVdIbPv5^v3|-P_3~F@>$iGk?eCX+WYD%yavx zKVmpbm(rYAj@(j}f)o0?_U4-ftk&+HM=u+@7}Bn9j{l%!j-PolEo$vAKzGIh%fFCu z6n_BRIF*y}@&J4SE7fZ=?j7}M{}wRTj#myCvw|Xw754Me&N!B;zkstz_n|-Yk8Pgk zu5o&21CUuXfTI5jfT=8Z_1|TKGs$(W`2s7lt}I93`9&L=2bHbJ-&per8VK08S!^Rh zCO}lyLP@mmY}TApT*{a>kd0z%SV9t^=GCG^7qaJMfzy=0r7nPHSk= zM41!QKV)wpyWzGT=HjdiV7pRO`vW-?o31mp zy^-}CvU}QX9lQ_zc-0}~+N%!v)aa1XWBu~4{_5)g`1)U6{n~fGZT*G^l1fAVXqFMQ!Es}DYKcmP+W2}Gk8e&tu*tv>fT`7a~0 z(re0xAAY#{vw!x_u73XKe}4Y{+Sk6e`q`iT+0~c6^riW`|9qn0?hpT=f7PNT#0jKv zRMwEC5LzPlo>L4lI)FeRuAN$9ewp^t>y&JOrV2jx_p2U`mAM97vXb`UE; zldzqP^d6BT|EZj3N`6*T62OGW__f5AO%!MXr4Ay1fC(?f>JZMopP*kDus{&ysU8#E zg;nXUQCkM1d~GT}pQIRLBG!cSY+rr4ltlsco#b2wRXaTY$}=A+uE`ITfD6s@3+k-c zwdlRr&K;%j4k$b{m@mL8fOHl)x0T$mcSi5dy@Ya1R;*Y`wX_~<{V+B5z7%oyE>pst zIp~jB%@zFrVlpnqrO9d7D8%>mcdKs$4}0H@`KM1PqLcRIQ&q4;=_A(1Z_`!$lJseS zFeRFDkF6cX(Q{*%ic>uD-?=C0kSc#t4}EC#FV_n zKs{059jkgY?_*q>BSmkY0W%*D>sFHO)NdY{l}z2u#&XK(q}d3yV*~?y%6u4TOY=6K z)=u-b>pP)k`Q7I)0Zt8gW4a{gZD*;Q)p^_zy4v$Ai|IALKpv_$-4{0Ik79YOFnSFXnbR|mS|nKW?D2P$q^$lZC`R1 ziaalU4K^x}_~bd&YM&!CmTTRd0BZ7mdj@oqWHbL=6VPf59s&6)&uu+$fb)&D4`7wL zrg<16SHQ@#*fmHV*sm`A<3WLS$JP22m?5syn`a*C)Zta zg=}0l(Z(-1r*u5vl1SOaP&#d-!^~CLx@j#pP{rGiaM%M*q_+Rt0x!xbzJDq9RJ5D?{m9cb7S=RBQLs+F)BMvM8Maw7C zIwL$C^5M77e-pTSdBFF7ya#>bvhwn2lJ^rUIqs8WV;bllf&DMTrQ z{+L<=J1eZliF0>m#!dnt_|JrDdEQP0Ug;nn36@b!cE!<;&vu_N9peiWLzBM=p|@rl z2@bBAFm|Je3FpO&oIt0*18vxhVFF_inTK!Q1DatQ>Tm!?twe^Wb|)`Tx4s4Gp1}w;{hnx*>@b1G+^_NbCHIGbx~!pE`h0p z<`d<1-ELSZ>1~2KXG`arc}IR;31`nfeA&AR{w|c@ptDQYnciHp(Kjc_jN7%BlHig9 zn0`xf4>%&UC;t|Kf28O)-hUX=>@wlzk^XbwAJrM9N7q$iLUXc?Zk`|tQoOT6i<)#M z#*Fo%lz_4#`MQm8UuO!#x>geE39jR$o&aX%ni#o!%A^e0I8H4E0k8$m?kR>w4ob_WZBq2^gjnbt&%!>frKK3^UqUk>)$Nz5)G{kguHYnAk zzkGXRi~%wiV_R&7n3a=hiB@m2Mq3x66`by_IiqtPgf4-B{DXr!%JsJmCeZnHU?&? zclj=c8)Mh!G0W=--f0sM=mY+i!SKTFuOIxx0Hw5-#MADn{!PR2Gt~n#4Ga1R@L6Nl z$gs~?VH~)N^>fV3v=?*glM_%A`xHyshU;Fmxt@Z}LCw~KAfQtzkI0Cpf^teF61c)- z9-1fL--NZ^mK=7ORCin^zR!F!FU~p8z1t?}T>HtETn8qK)7%;c%7$qjP|=q$Rz;BS z-xwd`HR)fN8uNc?Gg6RF@?eo!R%5ne<;h$;jM=^Kk~5jZ`^MVRLHqH+Z4M?Oj60BH zg-ir=W4ksc8$0niyQk+|H9 zH6pVUU+9fZP&q#n2SvQkJbcw5uR5g7(QIr!JvwAkS~b^M1FsUIozCO$5%!<49)4Jd zBsoTh@V$m{(mzMCqm6hRMQ#~I%#QUe*P)lB?tb~P$|uX*{mcKn99g9@c_~aw;h14W z?9|d5?P?d(QCx&JYf@J%rOrrUye~QX62gJD7xtrojLqyAF(01w$V9ux0+B?748;+X zPzBmmdpl7`u=M?fxm)Or8^|Q&r|ceom<#gcxC2ly2`! z^q-7IVGu#Q3*}pD0tHjl?VPCn zy=#uK^1S-(UjH3{(=j)B#=>T(c=wG1f7*?-pSEhr3&S%kW7B5Lqr9+bdXL;b7FC@;Sn&)C@#N6&R^ zWhG(G+&aL(RVk?Yxc;oX=-ukQu3X5cC?)WPmNCL$f?@1YL{4=+f*Df>93IvbDh&lOhveeVl3inUnFPQL6W5Jq7}sZ&)vDv9*y& zIc^_}_pdhhZ2j0;RBl~CsXn||Kj5hT=f75;dq)XL zdRJG);8hB+DrLc$Z|Y6}g9$Zr>Kzbtm%kyPU+;FT*HL6|r=~oU8M!QsJgn#S^Ml>} zO-K7_a|etUys$RzQyL?`DD<_`5K z2flz~+MmCc_6G9JDr=!NYrQpxG4C5-@zDnR;9ar9MadRr+Z=klC)>26z>fPdKbNSQ zOOAPVHs+H*^re?q<+4=T&?jHUdJrh(TJXL!50e|OI;0+X)giAsWYHlXe&hcCTjnmb zd2u*-O16?oY)!Bg&FD8jseL=al=VU(QZ5A00JnB)F(nk%d$2Gv0f1WU&UU>qbHvst zX@WbnYpZVe=hpc<@#nL4nuJsW{p^}kyZOE+&sh}H>EYWP%M)Hq3|Ogs z%CU#a@s&SMWii{eTgSXnbOSK+)oT|ItW2EJ5EoaFelvp$1 zw48n=IwrJ>4opGhJe8kK+3DBEZ>;|OpZUwH&;9gIt$wSWz}fD4;zIOAssA#2Tmxt~ zA5e^vxgK|%^L0UH?@?BxU{fLij+iI+jY6he>YK*Qy9PI@+{w_N6bO@++k<>Y7#HWQ=GWMX2QkaWsNMx2mSx)vJJp zImdzGL5fGZP3eeiweQ6Q|qfac1LMALz?)|g0vHNd5OjwYX%rEvXJie$C8{Zd_gWs?zjtkoL3ge{+TTzerQ_GTCExzU$XsGhkW{UNMrbM%FFiPh_ zQ&U2H>aG-1wIJk~u1b4CHUYKjqiunu%#j{uQ6+d4GIt8FH3?n)v1OA#mD8-c=UX-` z6roRnSGDct*H-`0@B7f|HMkNgaM1!D^x8%8nsl&TEK=^VcmPBSE=9gQ$E*Qj+OgFy9YfXW z9w&mly1sk+tK%b($^BN;ZT+|S#1%=&=fGK~f%{mU<#2Q=LA#0=ddBXYm{n&?cR)6U zWN5>N7%lJU&5mYz_r14s^2IY{I7%Ma@BSU-oNwNigZ4Q``~02+=5*?X7)EyoI?cfe zUNFD%DbqJweQ}WzqjN6g za4}c+H_g3D3LebU2m7&IHFqiBHUjGW<0HH0Q zdd7MMtn%~R0mlO#UAuE~L{XtS9hI6LIT)q-UD)537ogs#yz|Hxp8T4X5sE^x-vhmog^}+V++PHz! z)@Y-wEnG<6j*lGx_LBRvR^OZNSAj{T-c9N)8=-|AZSz=qltak^l~WsE2~$gb)3J5U zi#f{70M^6j(kgl5oE~D%C&NyK1bf$R^I3f!`)e)5m|IWMt-G&;K%gpz(9*Lc3xn+i zY7|fupl{<-+KGKMuR1RB zRfl|%I)v{oIl%aD{*@>_f5%rH@@dl{xj1~Bvi*a9;1B%ak8|S>-}4v$(qCGAR)oh- z{R6*;po>kzCIAp)UW)Y~bT|BIV$aruOk6 zjVVj$O%(0Cn2@l898)dec%j_Sz*RfshllTwzxj5M9pj7Vy79deTC83<`sQyG;LMn_ ze3!_L8Sr@wf>8gRoOL_9_=%`wawxx9V6hSaEW)cJh)zAzZg`y!5CQlsSJz%{G;qkX z31gD~l3CF1Y0ZSQwkywpJrh>)yC8!}{+pi?6XH5H5JT`wf9xM${nVfMg?ZoVfB93Z z-9P!ytbXS6fLBgocD<8CHQyxnjABdoP;%wUid`9J{-Q~1ubS^u){_V9rJX+A)Q6Jy z#ujyA12jJEpF08?^^=I!VLXgMK!`e}6oqJeaJjUC7RzqlxMM2wn;NqYKpv}ApHLff zjW7KKFn<^*vBaDV(0Xar+SVt?o3|Kto<`r zd|XgYdGk`BlL)(eF;Rhl(nhSE;<4oi72}ZE3!mV6eXfd`u3`n7i!rH23@GGXWU zmML(nKLV*~^>Uz%pIa;s034H5`=4Sj-PifGI~#+|nE#DEkQG3=_pF%2{w`fcrt6r& zn)TS)8RnNMGZs_bgFW^8B+%CHy*}XMX)`97yieH1{Fx@qzGo8X)w4M^@AbYmA-yZc zxOG+TrGUvq5x36Nr~X_611EixTR`UL7(W&FE^ZL|bqmDZV+r^AvYK>eted3g@m-$J zfhK)XpEdWM+|xRkvtwiMTpQ@@v$xpR81tQH7unf&(-D0?Esb?FXFMmSFA&n^tW-Ad z{m1H?sXOz0cA_NOET1 z`N@1H1533p3qdJo+H_UmL2JV2)_c!=FgFUa%Jfm$791u2^ zZ=KnDdS`>@`-hTd`#yFufR&;@0;~^!;y$2kvLtDr)nj|$2Ut7Fr~CZjIL3}oV{P@u zG6*Dxo<#u05?{#jow-6_^i*vmQ^=2Sc4>Bs{B9%o5oWw`uWp^6+DRzYJC?J#H~Ifw zb;u{8Lyq^~(f>B%=KR)t$e^#oUv}mFu%{gM{8sX%yYOKl$sMXq;1N#u@31#*U^6>nhZtK% zImF-ul;#8g(R2yv9VY5oT>=;>!%>c9v$r_tl?gD24I#HUQ0jEM(^FAa#jZAZyuK=PbuE=_hxAhyB~Xu=;0z_K&RoC*Qv>|J~>Q z(bd29`@hC?D?b@!bLQ{0#eNlo+Oi!#7Ls%r8p2e?nfw5S1njh{fbyc(eIGCf00NJJ*@9UT%=$@l6k`#|K>>B{XlWXBz4lcz zKLMag2+I#CX3@|sCj2PcsbeP;WZoRr;b}1pDJu%tm^|4mq&((?g8&+k8xKiCs0SdK z3Ebby@n->5eWDvqz{7oWOIwzdD*=T5j?u-wnWy3!&9}_7MRA&gWzesUIm5fEV`5@) zO18VERLd7P&(l`{qb2P_>RH{*yK<53Q;?Y(J$-E+uS@97{a^s3w(T)ny`z&j&M}#F zmUmt0m@U7l6EM1rt?`TL0&up0O|@)o1-f#oZ|D!M1=P!_f825^V1Y{Xpmh8tLn`c~)@3BXe3TP!XkjZ76B*$@{l~^46pG9x^9W z%va2RnGa(otIMPW0yz7=QyzA%Z7H|Wo5a-sW#=5vk$%G{wLk-%)|$yQrx%z#d%lU| zWUOtI*}XQ@TM4w7G<_X-(Kx^AmrS!hYtu5D9erB+&m!+VeDx4$Ze5%I?_zg>_trzE ztDX`6H=70XxZTkn_$=q&;tFCOyA01{JYt1`lE7402Pny{Blc_C2Fv@KKQj^i%=dFI zidwBb);tUxO&|K8`qVz-d71B;5BVJ0STc>y@pk^sRbV-zk}v6O6g_8Tl{rCaJ$wZC znO6l+B)9f~M~Y!fX70$0mUdnCgfZM{S1G7&%@aK{?06fs(mowA`uTJ|1MydWuJeT> zQ`*F~j@QZIgdxUpYwZ>2<7=B;eW@L-oua&bFpinuhe&af%jZmWW{kSxi8|$|8Gp{n9>H2p-%>^)nc;7jQ)wia{e zA|BhN6CMdr|0O%9dcs~<9D%`<#yneEh0Hcjf(y!VM#PQq4um8C^Ib|AbWGDFMuF0g z)!6f)+QrE5PwCl9q1Y3G`K%CGca&>>Qg0^O4Z{$FB?<2Y2n2$ZT|!(vNS*#tNlF$_ zN~u3GEgcB)&h;$n_5@TM^2bw8FZQpUb>LMR0-xnCGvI|7b1sIO1OOI6eZBv}%R6*O zJ~kM^!_hN;f4%yj|M2fx z{oU7J)uKc(|0069wp53JK>ZS9IQ?vKUtjl|dJ?qfhi|EK?2tCMYiB~q0J>w=J~0u- z4zwo^NKK%I@rcq7=-xkacpnq8$0?1#{o^;5pbozuJmbkTQq-ME>lXt3MY)d|PapMO zW4LCfYutwwO#1k@6-ZH}anXB^f%0;jeeWCm&8SBGUes|p<<6O(j7>gj9_U^{2U3;X zXy;m_X~TlwFehRot0jPK9yH>OZBd=gu9!ORKi;c90Pf7|MfnxzQy+GAXTMFsyp$Yz zgITORVL~>18{4RK#MiboD058Ae7ibcW1l6fPEkF%CPnwGZx1DfZ8(%nRHZrz;pUtA z090KA#T!gzk-%q4a}JoEHdK=Uh0$v5jIXBtF$%G>`7feA)X8SW`q_vQopcrNO~y@8 z<@^A|B-ptCl*cb+TLku6N|u|K`r86Yd-HbKxf{%Dp#0XEwr-j+Z=TTo>hUcn!o^Ml zHo(Y|11;RNFhCuGyO$_ zw)s*tsE_>{-&sFxHC*5PZ>+6*>*-O`>gHIYHdx7zCvz(wze@MqkUhzmwbMeb1ou>m z3T><|=4oKLjZiY8VlZkJ?2;g^qSgH%A6+X5xxO{tpF_Mb~=I&chPjbbcnr$%XT|8!4mSM~JB8?!|9~?SlCM z*s*1grRYrD6ly*?9rxozarb+&$6T17VtFonx7y*y-YvUS3Y(Zb#->o_9r&JdiVL_9 zj``<3W3YDK9bq-*P|Bo8vyK@$QTmDP|KUIR&wJJCAO6$->FSUC{;#Yy|KNW0d;Xn& zVfAz0`sY@E`{x61R21d7qX=i83`poo%82PjKWzE_oH^59m5Ri3iV(d}B1_&Wvfl6K z9G@-tqEAaba~}{bY3!}tJ`k9GP1&BMB^kkx^3>)^@4hPeGyoW2>wM4N6C1X=d!q*w z=AP1vJOYJl3h??3KdJy(6=kZV(p=-7l)9(oRP9T8CIDu>yh*WFQp#1PZv!To@~{T} zK2T1#@`HuVJ6YtIR`IMOKe8C#N{TvQp6MrIs>sArLge)nQpt#P709E+%VD>{(CnwJ z-Cy0@k9F$z=GdWN3~iXe1LIZ?Z?ykCypDM(q4hJyEH-Oqp0V$AjTqieewY+7F@U`X zxN@qg=U435>ksTmtgnf;eC+AZuHR9}_o{W^-_}@O#Tu)3O!U;XbQ>vtV-ld+9<2+G z{z27C>&Y9(`QGtSzM+KqlQzc2GR3;i*U#u(>x0USW6*excT>CkF7v64nd=EaOj+0q z%(*e2GK0oaZKMdQK3oO4NqmUWlhE2mt;Lhy?c4hgS38W)0U+;e;0Ivvn&0E3;fQWk zVx#h74a^0=iCx4QhiD{?c245EMuf0qlnKpNh zEOUoes%uGkeRXQLTDpW}TS8I0f{2-iItjBK^Ezb_FsbWSe`NLV{zE^hzBFW7OE^W5 zozIk0mcaGHuZ*cBh9k4kJq98_wl{p}mj2Y|1xVCWfb(H;X_dw$#iMru)3Fit4(Ijq z>TLks$?c_{N5{ccPnux$5mWQc=PCUdDIjqC{XC-}l_647mfBrnlW@oJ06Z@d)&NX-?9hJN;N~ z_WT@?bF43CS4Zgu5b_PY88#SKiir%wRr0axp3G=%Mw+|(fPpHvDJkgSklE1~AEZNp z=v{BD0(F#gDJOKEx-LK~U=r6;FiR$}yVi|zy+k^~dCB^X>cKlYuA$ z)T~Z@(1sx9;}%kV7n5c~RdqU+D=D*gK~I18Zb|jgqe>T2ilj`l@o3M+y-{wH)vPE7 z=M6Led$5^-}Oe>n%BW87ADO#*zqV+<(_Pz9A2d`Eo`xbA3S| z??=|g=v9aO#&t-+TCKX(i?v~~STy&HD$xFrkE5^u-_ju)$_4WV8cYo}sSHG3=Ayrpj z{}2D|)t?s!Nd*q0*sW_UXNrQ2#$OKJE=sf{y9wG+C4_5AR~=F|y>%yD$}Ybn3Om4% zqxt|$*XNT_J!1|6c8~w-pIQCUf8}3a{n7vOFT1z$kF5T^zx>BnfAA+MMT#1$^$MgP@A=Q&dhR{Iz+BWk2qa{DzA7i5J_yQJ^9779V5K+3c*GK(fXjpN z$h7+S^qm3a!!~)wQDVno7DU}0+c@k#3L61&DI8)%|Ce4SP;%KW;4KDkl#jU(=xcQM zfJFzKSNELO8z6rYMuEl8m=nMiNmyRA%<|>4>-+Wg9p>viIlWSX_2@1qdynAh352Kk z14LdzdD2?yVXme4frdRF%$U~9z`6O|K*@M4YX>8PksR}0)iEdXvkG)9D5tpx#Q3{( zIsu&xw&Mgq%u#B5=<;_eg1PViZ}#2<-tx1o^L+p3f7W}evQP<07$7PF4FtsvY!Hw% z3JfC%w#X&H=8B_sW2?B*FwJ0#+UzI;wjhWD0hAC_7#BVw1Vsf}8X7}FLXx`M z+5YqW{@!z{DiENmQW>X``zBTQ);a&>U7q)Oe$V(I4wy}9V_NcLFt)PNQ zo9IJC;I|f#W*qL%X!#H+>Jz`SzKq$hi5b8=XFQ{5SZ~q{^_c06J)^Hun#HXhqgEqb ztZXMNJj7=*!p4vc-eHUzFQoBcK#wk4r=!-TlUJ}u=&N%nz_&@ewHyl9@oumXj{?{e z1F4nB^M_kp%!!fYc`nVYdgKx`o>QK`{##QTY$0W=q}(7 zL%^XJ977+!(qH_9jLoUjI-nnWD#BkB!$z#`2&yKe+N9zA5X z`(g!%#sD+vAy!Db+@eG#n-}kb{6cnV5owS0lUgk$B&hFkUr*4=VChZhOMryA93YBf z%G}1Qp|ZqO+vIN+c<)>AnBRwhL3`=76joxrp(Q?d4QuHe=U+bPys`HQQ!%#GW4EX5 z>oI+@gv&r>#m0Vdd@2lH>-pc_x+!__^!yEw!^tccXHU5{j0IljdBiFz`!eL@Wype3 zLMq!WWwo@TYAA6(D-Kk~^-9@pZW$toU$_aCH}HZzsv?Z#7wolt8N&P@rwqwroy1@A z;#1OeCCF$j`Z+L$C-ug#qy->h!@zf@3E#~IZ9ZE0cXfvdC7%Xut3MgGPUE+~+CqScs$XeN7CMP4)@`l*um>#WdmRrDM zO9zw6!?Rtw7~-dY~_ zbU%3n0!JaM287@Os0uug&bab$ZP1Uj)bHc{%*z*QIq)pbf230w%`CWcx1Ny8;A-N{g^<6-@Nox`nm5 z#?lwhO79gwXrKYgOd_<9CnY9NA%(zGMslt0J=Y`ForDu;Sy5rAOtrtVU@Jt2f<}pp zn+Mb!11W?SJ;JOHK(vDYoH6yVRPACx9k9QaST2WH`Z{ADpwU?pYgkj(!X%BjUZqVJ z8#*%^T^K!L9&PIykDde(;}BrSxX~8ylzMSm2c2Z4f!e>ZYXAY~ZZp=(Iydgg9HoQn z*OO#+xPA;EZm`sk*f(3a8aIhSOt^lMOMJWc3T)V^?8}Z)C7$SFV<^m1{eDj%gr%HL z@W-OpbS17?Xa!!Q1<)3kqu`lUm8Mfa(u4%o)cTTw5l@xztmP5&W~Ova%HU(x#5GtN zH;Hvt`(n%bs+0_jMN4y^(@*NcS$;>QbBVIxIn0=30X5E*%9=_IAe=d{e}bd+xvR$M zRvO}+?AIwk*tkF2fIYg01x+BP>LU+WFb7F^*y7z|>5kE*{0lsjwXi6$mTzPBdhiYT zX=@0E#~cbo@kFE^r*sd`n4)M61)uQIrQn`@w+B%7_ZDzQ6&0w1y~vy`C~IOCd*>d4 zM{1>Bp9mv8^qHry8e%%FGdZCyoyD0!{e;-SQ*c2u8I_N-pj%s?A%qr1itkM(VSs$k z9zzxk0jqQ6hT4+6c3*}-C#OJ$tazX0ceK*GyZR~}(40IWO2^GCLwt|?Po-b(-Xp|m zh@nB{-lV^M8FKtGBn;pr{;FK{ByRkCx5%jHAa!fhMPR{LwXh^R7N4Z0B-#>G0+XV4mC;#)0rlO~z_FeUBqoIM z1T%1ouSSIUa9;tj!8rR^Jr2lVU|z;0$Gpiv|qC-8`4?EPVjanqEcUi8nD2 zTE>|FV5D(B0A2xd3z)qMN<-g=f;8@oj_w0C5$rjQ!Css|yYGeNw{CFx8_OdOnk4ei z*q(K9X`c1Z`2PJ@-(qLrjN9Fo(lMlTeEO(+^A5bnri#W4osbaKWZTAi7LV=Kr5 zleAE2X{l}$0T!T&K>rB+0T}?_wEIi#Nzya~!S~ z&x{q@*&x$c*&WNDyz-CAeShWR@`N|% z5v4ru(lUGcy%;-ySIYqNVe{WMKeM%0{b~7^=RLH%C;#HFpLkul{yC3WMZT?igw+Y1 zJk8j@U93dd6tH%-<>P<-2j#I}`#9XdpWFVo%RW+mf_s;5%P~ zE8cPv4I1VgOM~Z~vIV)G?l2DBRM~V|_^^y>3ZcOPLgg=MwhXN3@0f!8#1 zV~scy5At0s7z|VwmPL+v-UJ%LJVZYjq&~`6`m_RTadYF>{a|Mkm&)ZDJM6$G88R0G!>NvN{p^DoyS_6 zJRn;Is^Me|U5JG;DO%*TV&y)q?M@u)Y^qaSbkMx?An6;!H6&YAH>{x;&wt%(%AId_ zVfohkeRJMepF#gw4J1@wc;x{UW)(ih`JAq3`(ez>0OzgV3ZYs37+iX026 z)>E_PD_Mqu?^>Kmnu*9rl1=C_TfW~@>{e=#&SX<-K0_RY&6Q5R3BQYY9F)~-W zVQ28L0Y9~Th39Z(g5)DjoG0cWnY6@MHSCjQKSRH)&y2E83tXQg6F3YFfd}h>h{DZt zd~J$YyOz+Mv7^$yT(f1YjGB32XCywbd87W-c_tGO*apLryu;K$By!Wg7so21OEj$ek<+ssmSzj;7rx5r-R<0jU- zFCs&r377+8*J@3pPsWDV=9p<;K!$|7V&T;@<9*hk)rzf!dEFe@=_o^*KF2Q3uVG%R z4Do#Pbu;l$Z-|BE*D|D4-t(VfKFW|0`!h1c80#-4L)h!NcKw1A{8>5V3Ep&LmrF!7 z;2NP|JuF;+A$As67ll>+Wmqk)gWbf25lI55u|8QcXxUmRAz7r;n(1OeAki%Nx*%l`@>p#^uT*%90ELe4jWi=Gs43qb^q zWZIqpp!0Z>jqC{qm=5F8GoEGwz08RZy71ys9)I!0HdB_NH1@jr=CI`FVqBVjKM$9-TF#2`-*tOf` zuO9zn`HtUtZ+Y2$4?(;N4j4R)agVIrkpLV9YhZlDI08#Xt%ujS zHqhEE;pv>Qk~!<78P^jz%V=k4GS-h%h%}zvE2!WUjMO>fmK-1ECg7QU&HBv!24KYa zz43u_@~*b27EKdfMr3v_po>1=bxr>ndIJ3>bU!OW_4?P~lgSHi;@=q9dql#O+qo$;4Td|?*qHWsk~@bfml zmzgsri>$MF))dS+t@LzB{ACa2#~G7HY@=)?K@47)eS&cHTx^qLxHK(bDsvzoMJZLG zVu&UaNgRe6G-R#|k~dV8=!1v$@diMhpr5c6_OQ*e85TH~E<4t|Vf|{{qR%qkb3N}o z2O!+4D#jJgzXhA{_5fD)-2&GvkBK|pXD5t>HBR{x`dC#jXq5Fx;*2yd{lMcpJUja` zoq8Fve*B64?7OdSa^o2?fW^*L zFa{VnLF%>y0;BcLj02-EtXZA#E`*%ltARlPAln@?S+O8Y3<|XTULH%FzamT)5KTFv~{>X^8-8+VODZSB@Qm=_bC%uXP#oLjiA_ z!8Egxh!GR!m8&nfSGn&u-LKr`Y}O7TVbM|S1y#ew8mi7}QCi2KoZNviczC(s zYq+umDc;ay!LiJVM=qJMEHb8fJRDy|*jiUCwdS)%=OMXQ9Cs9w-hjSXw4 zcUQ~k00?ae)|`ZrSS!E+W75j2fLvfMTHtD*LnnPKfRZcjQme|NV+;<9s_*&tqa$h1!$A~dbsBCs6HM45{DqXxuUO+r-EVJ%q=aGB(mHwEKX>m~n4whWHpsmKgV~yjtG(g`j zb2~Kt%ltQE^ZtZSm72Q^E^h+q%EKsOD+wu zT+cv*11w=CmbGO3YZ=p0YY}SaUNCHn)dA~5i?Y?CJRA2XK(GM(F0{O{QTg?Z=a1xn z+}p60DqGfSYyspppabu69-MpVHET{VJytI3o^~jg=6cIhmiBrEXLzsk{ zC_~gM{L>kp1nmpT%z9rdwqIC=$djc-q!F=k7W*%hr*c2m0`p&7hG>k5H-P8(yH;zP z*56JUe;UgW$FbL8kXXqO|GjQqck{@Q_47~kXPxyEz3WDP-w5{fo6qI| zI|GBK0LvjIH+mNA;y2(F8-|f62n1)83>hCpfGMPLx6C;Y)^T{sK@XyCuxi9@;CwJv zQCMUV}G2G6I`u zVb+=hME5>%NqOcgj=49#5;CqO1t5~6qy%WVsV8X3Qvp~XFu?oG=?*D*qEMHy=S20I2Z06S(M_mkBBAnH%IcotJI$+%`Kx%CWRI&+kiU>?y z3|Shix)en=6VT$$IRXn{G~46-$^1o7!0c0DUyBb+YDvLY1({7DWR15CgySx8mgCVG z%nO!QqD)_fRA`oaM2HBW z=?XL_l!O)R*e6b}wcTtDV2`WOA+>fBvn%joE=^ELSPFbV+7#5pYoG zXF%_#T80eZ!&iQWFpe{OoWya-3B5{( z0x&JI(7Z<`PN8`d^o~b{G@KG;({nZFS+(+oE@$TdG?yWc>sT4$zt?R6AHF$c$olyw z`V(*`GrFm5Wv%itXrc;44?|a5v`W7jb0bapeHjGoNTz{M5x`jp*hB<$$S^9cdvk>y z+Gj+Xu08+25MmkOsxShsGc&VAYZovY^R|IdQA4*)jiUopdiukVQWFa0xX+F}AMm z+@#UOSNlNk(V$gv*#xEgIz2uo(N3A=4oHuO59=ISoR!N{(H#(Hu@h^93F;C+2^{OE zK&e_kgW#GuuFLrj8MauuJjGyuS=zc{PK-6vbc`C9uC;C&ZB!u0x6x1=D&FsugWijU zqeJWTj9N|{1F-QImJ{Qi1aU5kL9Y6d7HG28M5BNMae!*L^v7P}J}_pc2e{nDk}}3> zV-Rw{nwAXQ$V)5nR610bwvWbS2D*GVE8Z?btg+i)_cdoFS1cB$mRcf5! zcG@8Z$Ku5uTK`90__%VHA9*{^JGOmG`Gf7>Di6ivvIjtJa5Wlv(-B`p)J*1MYM?Hb z5iO%vyzYm~?H==A%G2Nd@$$T{Y|9%Tc|m#f+kD=4mN)OcxI7rut)Y}dOYEZlE@QY- z*A75z>5oYksf9sn zgYj9$7-|(sDTde@m|g&{x_IJ+nD=#g5y9@U&65s1@V?b@${p41XW!81X*B_3#hmjA zlNjRXT3w;E7VAK?Q7*%Cl}!?jk=ZhcUze1MMBIQ}Z=E#Ve+#Pd8{0Y5r>!+EE?4J( z-|6_;1>5P47;1&qinQ98xc4CP>``k)bsYVa;?G)ht+U67jx@)@^JhC+xUl4*ki@lb zyc6`QC2wLP2hU5qW~^iM!C0h}YN5~T*eIyS5Q1HllufLT9U5|tz0$>p(u5_nWsT?s zpG$*$=DM@yT6hw##=84n%$M|Q-A~5D_)G z#r?qNnq2d5z9$B7K_8~L1t&7KSO7eY0xKr;F=kzi0qQd+bFO**@4cqn>2~LrN8k5h zSm_8(r;jFqc+!DKzKspnNPRBnw=%yu)-FtMsV_O2 zMopbOEK$C7$UgFjHOr`IK{lSv*h+L-jGVaS*{7DM!930~>87Lq9DCT|BDN2mUJXK8 z?7sm4)g^CI5bl0FAo0d{1Q`mmNlkVBnP=9a@@M)1tx1c9drVv>`npa|GW4aT6h>w~ ziT%vDd~0pTBSVa9w>Y-@*)!ZdhS8dMIa8dyY?9gW$dJQ?(TrIW&ok~N;lMS9cCezJ z?lPo-Coep8X(dAj2hLwlF-xiO%Gh0K2G7r0j;&>gao^dZLAz^`Yj~GUrV_Udi*C{Up&*is zGm>CA3I;%fL*$iwPDU(s^a=?L3e*|aKz1wejGqKX^xpC7p9Ack^^P}}bDs38{>seR+PbfBklO*yy**gJ1i; za>=8=B$e;2g*AuaT70;7kac3FEW9ir*d*il%-i3!T=D0hDAyC%Z`n>ew{}JqyS7Ns*8TNxhfg8 z)dlrvFtTo^Rf!&ScIe&4wU|NO#SKrn*TxVvz}A#8iZ%!yy@lxL~t z1P$C*uBElV`kS}myGj!?;tpkM{ltRuel}?sG;8fjS(w=(+;dz{#)SDiC>79wyB`8j zz-ckgn&*`e4fMA@nZVe}fyxK-V&T~-75+CjYH<5xXg_ovA{Y>+p4ZtYR!SjZID!Jk zb6DfvWZqPa>S?(!7(qTXt-=x4qS_w}x?$cFGsXmH}x}bFoKVPXK(qdnZ=+fe#(5H6ZaACEHLpUTB`|30_(mpZ7L@)MFaOY$MOjJ z%p&(mGU|4T-`X*TwLZTBJKaEZ5<-$T$2@PT77WewP^_i^j6U>c)~Ms|CmxLM0ZfzF zV^Ghnn(*KbK|X=6P~E%=N<7Zt35jxt|NU5&j2OmRe_0yW_d z9HTZGA7bdl`q76SGO3M$Ql(4$C0Ckxmn?q566}WsVuwjeV*PorVJ!{rxVVNq#RltY_)!=AWZjwP!0^22ySZ-kHm)Kom!1wNQUUAbFW&cc<=g8KySM1eFW7&q2+~2$Z0A=LQ)!4j>wRs zL?*YqIb_JuH=NjSReGP;JvVx_z|2i)n;4S?QhIQ6@PAooEeGW z>16N-t?>j{n79HjvNte0Hkg}(4#U8GpQlUEcHUcl?q5CI-&XCS^4#~mxjge0&->Wll%ItI&&UuwV{@lm^4(uu z9{&~}>oZ?hp7`bG=ABC>X6(jKu~D3yyTN2}c~CmXy@Nz^VmPVU{E{65>%))^#Sp`l;^spz!e!9f-lF>F{fH`ER~{~p^H5M$S^#GnFVj9KF}ug z2GGZ*$0+nFkuL0YjVw!xfM_wg_;aXtrv{TL>2pJF#i_oJ#oFYUiwPtGUw$| z$lE<=Azu{`2#oo~aw_CQAjX>8xYof&t z*{V6|CT1DVliuDY7K`U#)zezv0F(oC0Hzi#-@P6hW!(%y?+&mN5pM49B{bFNd&Oat zJ;u5u&|1Y5ti>1rxy((EQ(Pb+ti;ATF$TsrkN1ITl}|#iel~T_P~NHb8c@%Z&Ai=A zNC#`g`!gs@tiVGBmClXIqsJ}!+kyhuEE2qk7XnI+o0=1{((_t97h18o9<`OrSw9}= zsY0$*#~w8P(D4}NVm5J~GDBVy3%x*+ewvNzF^-nRaXr}GtTTHKzG*2V-VA^w=>i1R zFs}#$KH*c8hb`(7wd@rww;mOjEP42dyxH@h1<0N8u(XqvA^q*E%XJ}|Jmv;}J@X!S zsC)VrBttCCr6;K~&fEEx9{5{YkdJj(EIrHmi^>q>p-0%Ih&K1-JawN24>8%u{bbgw z+~|wS5R_HD;hqvS+Bn1=@LQBWV~q8XXyiU!We9^|EXvI)L;Ux;=~}&cWJr~X>-QY* zPr1S=X$kI+g${y{#%MJ=2c`m3h2}_{PyoOLH5Zv{vk01D&nFA|S)>)XD;^6m1cTEGgrbakZ1PnKxz*3#-(tdn#5d=2mb&Iso_$ zps2KCtY!~7R)f__XD_vw(KF~D;mbNF`;p#i6>T_1U>5+Pk*W(Aq~FljFf`}>09Zh) z!_=taF#%LiO6tBLuvw!i^xTK8nOOP+-2#sI2WzI=8IT0n(E3T2c(;9`dA&aZM3!Y! zASnn2#TdenGfvsFx+8$|6~lbj;0%VuH~b3f5npVzatAZyn0T&=lr)sq>myHFmP(}cW_ z@$JA5Jwk1SJ9~<9EB|#B8{9_x%{X}ibL~B59nau#BlxNoNAI8GNs+!Bdka6G@39|Q zd(Yi&0gIaht<=&umT76h`hh6KeSS{aPkm^nyNNPnv9VG9Dzw3)k7@UQ(qqbhyeDo_ zT=};o8KTS9mgF|*-+z04_}u-bAqAP$2UN-P<|<^g&nH7tE{S!N2hE`aqNRu;s3sd_ zgOTyaBSU71WoHjV_wtn}lH8ekf6zzj-?7(DM;YS$?OlK65gFpY*G(h9%^^e9&p*+h z&1LU==SobT=&eVuf9XqKT5f-b^UJe;`q^c7N5KwJ!0=_j0w1LWw1zeYc#;-Lr!r>2 zCX}c?X0=ANH!hSwWw|!_n*~T^9-g;pEj!PX6#&>eTpVf%HV`pf=w?yk=ykmXz*>RbO%k zo5H5G&=L9KwtwOY4SC2v!(Wg2sn?VTe8ugR&7aentxuMxe9yoBoX__^*q?#po`C~j zT3&kIdF6m+pkvw}f8Dv|?5jRqe)`gPAM@${ulqA_;xllMNBw-++P;pAdMtvwSC-w6 zy{mleBOgBT2kqanKLaN)12gJ}#*&^m!@z0oMmbLS3SNW5SCAt$+eXB7^5gya5lCEK-h*Bg&k@samcwUvj=`Jr?_dbK*jllr3uFbK$Dm~ zVI-P8PZN&;^q63;2XKl*tJ_v903+cA#_bsAV6b|FW?FDp2`Vwg&}ZU_h*J^g>0;X2 zy*h`jqlWW8*Vvcq-&>w=_JhhR9nCXeU3Q=QaG>VL%d7t7-OJgWj*Kl$2n?Xw?R&Y+K4ICXDX=HN(EQ(Fh_ z^ZO-l|I_k{SN(o@!lS>T{C6%JAG}k!|Ci&6<=&=z3FiK5$~ME@0J$4~*s@l}Us#_F zDlR(^tL0{9m{|u}$N0C_2J3PyAm-Eqq%Sk97DG<|Q2RGy$Ut$Qpq5wHh7BO_rw@|7 zt{ls3=mt04+;f3*RxID?zKT_a`40tQeX$wmr{zw4voS`Dd9QWl@-=j4eMO&6Qv>Ft zk;3_|d%7pE9N92Lq3PllLs_VeIfUMNoUWi&DlsH(3tIEtF}C=dmI=lg%Mo*jH!a58 znk2&4C@CqRP2Y5Ho5W+BlV^2?z!-aNYTH_{v0Sl>oE_VdvMcm0f$1t4HrB=jk6qmC z6Ke?aY;|u7Sm(u@h- zb@*AImye2>nXg(T_V$zm-Hx!WKf0V-@|fT z&(o#nc}E|s4*ZCDlwNA0jpKuUa93NA-%>1EOJ$@<_>hre>4dsMTL#K&NYfJAV8KHT z<^3v$&@t}PcntW?a1Jf_m0IZ^mR-jiH!fOLr4eJ>;7vr)=L}?uCeNV}$I;hIK}^(9 zI;nHd2Rwt*BA`Xx(;JI4K;Xw;zMdGyW2^~6JWk}CN zp(Dl|hNf5Yn6{)m+H!d1F){?JJIg&F)^|Y2R+fT!?2*I?fkwVXhG4;#zie!H*n>2| zP4JdlT>qFCoWQR)?AZz2__>$T8DcG7FtZ4e5q=%Q7T9 z3&~`iD1*2=PD+>ESh#kXI0f&;oQhSEkMl&sUs`IPEr(hXxsMIrGw9cEA=0?haC*GIA3@&cBDmlYR0Z|F}HtfsZb)e$U6r^!?kicg_RLmjkxdFceBc zUW@zIBZ`PQq92O}-~_>Xyp}G#kTIV}u(2UP*sMK{ItdmE?~fIn0&z(h=7=@c=QH(T zs!JHt8rbEdWNJ~&npi8!-13pxa?I(>x`>QRR~&+$#SaYzoWbmBtwPQ+_B~uPC5zH{ zb_Rg^snU?efgv!u!@AI;KBt;6x!j>!P@qxcfpqKTpmF< zUSsljkZVC^wnEi$>sl5_RS@S-T%lzCX@E}uv_h_?Wv9>8geJ4`@k{3mI!Ww6V9A7F<7sATp@ zY(k@tJ|S2{=}jSM1vh=3c)ASX4GqaO#wxi-giA|ku*Wm|@V(AcJ#=UD9tCh3WWqqg ze`=O4^uSshkLBDN8znd`TdUsB=wAnuoNeI# z<2gfk3Zo7{bzXhe&K5N&$^7iGPM*GTn0pkAW9DWg|L3v+^JCM?qV~|iBcf>BL>Z!B z?7>g^D7&|08RD7iOOALP5sI+Q{B5vF4j*RyNML|U^KVv=<*@7qfDS%nk?551g0?=N z3~7;{NJKdz_sWx0GhAah_;JV(UAj`~9L1ptZE#c^R#Z<7iVR_|oVGHAS=hdgJU7)k0T`|MHbUk^WdqDY1hi z&)_)MFKBhVT)_Rtf(iWH6M!4Fdd6!^l-9wV;=mkIdYtszc@Vip0#&ca0*=xvT^rLDtCAXwz|(*89RE2dY{lZpOA4%S zLhC6B!@ljbyhz)$0W@UXXh(vMF@&)Yv%g*2hJxE2e9h#Rme^BgXvVnR3sT;YJ>&Np z_pBnoMLf6CM4zJV79OAQeyOa1hS$xV1ma~K;OoJ%W{=mT5O=;bTpz=!I7udA&PCnM zDxg1!KA|I*0$O2j)w4N$GRi7ScE?=bR2c#*Vm(y;^f=s-We5?ekkhC+li9zPX`U1c zR`8R*mRe+8Ie{*}ASY9xSQ=(#lvGD7c{h+D$~u)=YfTuZ$-dY^9%3jtUKwIh{yp}> z3|_net%&5!c(-}F%IPda9K-k^*dz*wGURAeLB2U;Nc9jMeb4d!R;AYQUi}5G6Bx8) z;|23O|{!f4F;gGj8-4|jwA zNu08I&kt2_;ZlP+EeH}HaNm%!DhBFXm4A%j6JQ9z6jo{*LW?B~evIp>Q*tU~Wpn_N zXm`BJ1H|J(Tw4VVDyF1?R-mCw*``1tlW!fUoYE**C3G=3nM+D=Bw5tWgN*5GNuqUt z*aK`3LF&+RHm|MBwA}Yg%UR4_x#sfn`ako^?|pt~kN>%H z<#@N8``F(o<^6wM{%)%&cRPdonbQPm`+R}PC*E3q@RdH}*rqsezUeoXB!!Okyga2q zw_A0=a4&mLZGMQLKJPYY>c>1{)?Ha%b=iL}-*w;fDQ*uSFniIp;Tr!aEON#szo(Kt zAidMl0HEoa=`1jJ{;&dhypkeD#v%Z5&P`Ym5i4*^tVwAZ)}e&K<%si^dq{fDmg2CUFVSVKe(M zg)yB|=sw4|agXjR?=(x??BZCLTh4FJeh^$&ke!3hp)dQ^08j*tTBMg)v~>dwS(tS& zzUR+me@l-%e-E{GNS(VLG^RU!gY%)KlokbP2gS{2f7#QY%KHJ8Ti2EANHDS=h6@M= zbyLefv|f48HZX+ysh=j8;Y#jeKA1kq1`Ca~0>_l?&;l(mS+GWXT9L8#>yk2|!mt1n zvD^oqMlnuycctLnB$@!gm@D0DIU5&O@Ft)~O39MZe``_c-fy9;&F~=hl~&PJ8xGE9 zj{%l3yH0W4>80>l)t&C%^ZL3jL&8Y}%DOlAwzsgppUc`{>2z*`(X@2C7npnY<_?Jw zDkqkFN;Y^jNP33lj#8TvFFgdv>rog9q>S^GE6JC*0AMGm9L%9X=DkR(@BzWU6w`4e zTx`{bnlNt~)7*QWF5<{@#;|T-Jt1TiE1)}$5?qd;V}NiAPe|4`N{uJRcu$|PECAHj z1naX8vS57czGr*WM-?fo?(E41KB)}podOv`r>Y{aQ zJ|_zwes?{diZS!vpb_htl4Lw_M2n`>k~6M9ONO{QdIH>W)?iIM7@;Bp!{e4A@+S-% zc?!>xhg2okzT&1ljb#Ya!eEZdkoyuy(A*%9-_hcEz2rqItlz>aYk7DV;< zD_aY*vv91|JewJ`Lxm;Z_p#*lj9EcY%DXy1L~pjqDLXI~GV$!EpYo6x)~dYHGnz5-Y!;+K5=QObA#y^RLAwUssRr*=c8rlej;}SZN$N& zy`xo+3`*u3P3`=Jl>jY~88r65AY`>(n_7vg;aH%lX-1a}8jA2UKh-R@iI$^avZWMK z!5^!dWzt4iRdON#?_APP9#9vBv1lo=5aSZp5y%aYNdEzyGl1b}hP#$*Th;{&A{GM^ zG5im!)QlJ^-A$|%&!G2ObO5Y>`%4#GG1hT~vPHqyKAp^Jf5nBM8E>6j;KXi%-4&N6H1?{^Ih~ zKl@~P{=NF;Ee}7pe9PN-U3qNzgTpV%Nf-XBd4?smbjZ2eDb&`lJ=YScHE+4i%y3rd*jP_2K(%3QBkm-Ju~Wob%aB$o zh&A_)RcaWU7P%$w^od~(SYV9jwC`cr>R-5>n&Sihwnm{l|sX6JG@99BeW3_}~TC&7O%AJsW(K4oW zGub5WOg`vgRoMH~R(bW)o>9K$c6DCY*QsP(`>>~#bh?J=h;LuGXQ4do z5YUE}IBU$&Bg_%T;MG_yuH!=sfA`sUQSPwjVX%eHRO(RtpcgBh^a;v0j&MlQNj^uH zv;VrIq%QuIHTSnM7C(ciV^NHyP9+g~;aV&38|Q1#djowe8KZ&pZOYkbDq$|uQ&u*b z{Tj^TE@m7iti&pfyFZ1Ry@UN@*n)2FVXTe1FQH|NZDZC;0dn?QN(DLBu>z{766U~d zE!H;eo6en<%QWUsS6nSi!T5P@Xeawv3n830J~jP#PQ6#lF5}^$DZ2xW zSf6hI%^T7Z-p!Tk=Db*FdLH+ydvTRSWKnQR7{z--{}w#6NBu!e!HJtR;m$Q*%Mjhx z@=-rODnp3pQ%}GD8ilA?sQh zKIB*%u02+UNESBYh6Di2NX*D)!OG^r>ai5E zDXqPvkkBGHW%3N1mQleu01N;vz^6wRSvyTPY7U+Ulvr=cqzX7HmPOx-dr>Q#0v0nj zAw5uU-FPE5en)_(NZMVJYwUhcadCou_RlmDwc{J>e|!N2!0m;>O2an5lA?NG92i50RkM_oqCjXb2K}AEf@n^<}R)$+*3Vj03JN!cAUDvi5*aD3lp1@ zFmd#VCIns>FZ02?ZZm(bLuEjcAhaWc(p}Gd8~>H;P5_?km{TDvYe4+tHfQ|K=#Pmw zzzeQJ@X!}G$S&6227u>D9`oyQk1KQm9mB!7Feu%!Ogq;vi1q7RXc*cYkIrB{SR3Ld zEs$&59GpdNz#-^iGwZE8ZNg_0=Da0NtO6{S6``YxtA#cOqjSpetOI3222_LKP>^@H z%yQfv*9D}i7(fq0=*uvI4J_BnN)sqN4$th+0WSM?atI+#|JX+gm&TYqPI5WYbXyvH zsPaJw0ZzbxffU)+N)E8og=*Z}`sa+f5P+>)t#w%EqXIj>p)(5kyowM9`nup~KaWGo z=UgEJ3L*1%))cVnXP({Msn{X7O*Zh4E=R$Z!Tc6V<`=&IVEMfZWNDwxnN2M!^IU&66lbY;=!bLUTxmO*%0YpvUPkV%;T0s};N) z5EVDHo(r*nvAkQ`&?s~;qYhn)rZax|o$t|AD_FD-CYp@K=QEbGcxR<~-Qe;a>(R|o zoRY-A-dwMt8J3Pfx2g(OPKfcD2ysJMX7tm&V6sMl9AoqVc$J}saciOBR(V4^oHLk-X z{Co`kdgSF8V}P{j5s6E}IgXVfUbg_KlV%oPsLb-Zp{I*bThxqM0r&C95KEbPddrYK z)K~r?k8de5#CbYahWPIz?Pii8N1lIzzuY*NJ;8@~x$_Am8JQ+6( z?)(Rrw_Wn=a^^!GQx2W~=JHQJ@__Pv(@&JU{K|97CI7HpzW*NIP#$vSpQ9ZfC?9?K zFP7iuX+Qg;4~uotn8AfsO+H(0e06!@75`9vfss$Ir?BXmyX75^|Ei-WRJ{Lp%aiYV zd#?1v5WvacJm!P(@QMBFc9}5}S4L=lcfIS~%hR6v{pI|NA6&lkWB;vOcP>Bz0PKrq zfQb%mc62~yZDg2bY~U7vL^G8=jf9Dd5alfx;~c-B&4dZGQr4tFSZlkoi8Yp%r@-o# zlzVZLLIgpyuBZ?>>nFf-S*mpZhrL#$KWQ;O=KV zJg+Zw1d1AhxVHdY6Rd`ov5CuF%Wsy;!q*6J6a~vUs8qDjnolN=Li`y)sx;~m6g)8L zfD!dgX5q*vUd%OsDQH;62+{El=n(6SS)86b$)Y=I2c5C0I0#-w^x1yrY(lKhW?v61 zKO)n{8epuT1!uP?tZWGwsE@g3U*w!h`T$ThOIrU;$^} z+xFa23S~p51L)ozx@3Pjmvh!O73zs8>yreN4E5{_O59-4)IwG*lER7_>&GvUhG2zx ziPfF;$7(HIq>!zNAJeP(H+iU7r(3evjY+++_T681f2N1|A^yuOU9(v2p8@|_7wHG8 zQ_me3^9IPbFnG6vB8K9)#1d=~?8IFnSlU&IpK+eUb6I->{82%GVm-O@ujYLPdx+yP7${tY?FKcEAZ4g;cQ zfIKba+zCGr)ccUt*{yuKwS86A*aQbwl>ek5EX61RCG@3oO5afug; zKhU)2@@lCZKp)b75Tn;2-Yeb$K%!v1!kbyc( z>>P|t#>*e;TKN!N1^TF{ zhicNTS+syohccuO32cSo%J6Mt&LcIkKz6N=YH+W$n^-KF2Rg`~MLFY}f4W@ru5-&n z?*FiI=8rz6yyR`qEZ_DM&o1|)e`UH+zTtzeSj^_H36ya2Y^jn6fpY*b7Wv{Kg#wB)SC^i6aK42-d5+a6uE{w%82?`ormezCfdV$X#^dt!_F__a376=!UI2f*0Gr`eIyX;YRP6c(Ey~Mn3>Kx{Pzwx%Lx499N|CuJs*|?oX~j=+Q%IjCqa%3vFvf zlX6^FvyP>2Db!Gp02_dii8KCgTW)a=KP_Fuw6RBx9agEphC*NH1vFT}&rla5*Lb>1 z?$*kxG7PMoYZ6M zxQ4KXmS-*58}leDq?JJYDSxB&l>a;zcFAco3ltE`z*skQs4U>AD&NjzGeYD506+jq zL_t*7gtM!SXSOty;C$?!1TmqdY6Z3fvt&NtPjWJ>1O_H8B!|^$Z=>IDv*ooHpP|e&X_85zK9IzvzBvc z(dZZ#&w1GN|Y zRKwqe*$=H1CD_8Ewu3u%0}a`lci3J4VQ4I%FtZXz6SQijB+Tzb7cjS_%xhw#cX&^9VQW5O<0PZ+pDg5=)u2#;kwT zkcMA@qjoh)rl6&as4uq1v&U$LJ7}*Hv|L@L8(4inU+KeO=$P;-X_recrtbV4UFAT<)Uz(sU0x=C#{dE5(BNpT1f$V;UKZ zj|FFr%SS9}q2E1R1;%h;H{>(GsxA)~6Z{y<7^P&cy=JF;`Y>)B4l4iqA9+amwP*Zk z`R%XNrNcZjH^wE!4eWddq&lIQZGP$oHTI^K*~l5LSY8Cw#ztB5OFNV!odafFo;e`6 zuSSM87uPASFV_Ygg+IpgU^T&oJ?EOC+AvpPKIM9Wy8YrAS_gQJ@lq8u%UHG2dVo65 z*2+VZzzu%4E}dlx%#yAR7mC`Qnm=O@SW7|1#o^a<^1%JL1OVC=_w{L7NdmZ6PcU|g z>ahGvAdgki&4TMX1zfSRxn9Eb0r7JSEDc(l<67luo@Ltuh%+gSGxmr)Rf^3SiO_Uo z0uKsH4oT0q%oEQ=TgbfzRT~mujWoCGl)2LCs0+%OjWts%2=^KbHD?Z7dtGN*$!w0> z=E)fg*O`7LUd!NbzOxS7f^Y@vKr#r%290UK$=bmToIk8XaeG0tj-;N&iqe8rO#Q@h zd*-Kfcq9m(bt)d4gB4J#)$A~Ii**i`gVoDW2hXL|O(&hX=2e?Csik9I*t)#W`dGC| z-`dulzsAxdxSV%Cb!EBqF+Ws3^0MEd`+kNM!EtHH!ab_1ln(kd4f|=94Uu=m0*`gV zgeEPmybenz@r%&IjL)O&VF}V|>N7**Jf|k{@XVDp$-W!Yw}(5I35bfPtJt+tF*Ck) zZSl1OH9-Q>kX~ud8;hRjC8^2}Q7Vneoe`3f(=D8ZRY-_mulaQ!o&;Ygo#ZJ3W`?zDnt68BSX@6D?-SBn44o|h~W*&5Zp_7#plWpEN;k+SUee% z{nzbaD8X^d5LPNyTa6>gK?`|X9;mi`8FI795GFX~Wt1ThL6yk*7NAttgr?!&{FugL5LW4*SGK@6QFR8+mBNKaX^m0D;8`xfGr!}dtns$ z9zl$-^Vljk&;UWF^=~2*W5e3Gls;${)}>Xgcc7(wXC1XYgo&_FSClR@U1zWX-sLsA z@#r(Z88>1Ov*R)QR&cVNI(j;4eFsbsrszozVZs41S_T<=0H(~WF0caMAbRf-Xvuho z)==U7p0MF(3l{r~LkG*5=jt}2rufD8D8KVZA1$x>>U(D4`7p^I0XT8jz_?)UCQ7Iw z7_hwrAX-CA0^2=&MTB|7T26lk&5m~0shKu28r^hPO!ZOU|46*h%1%hx^qE)vWN ztaL*$-$N8K!J72$K62X$l=}efDd5;_(`16XAe?j~ovo8KS}gs>xYcTzi4mSm;%u0WXq`oF3`X@#YGVk~P`Hxuy+JY* z|2cIt_I!&Q9^H~;9h8T*o`zCm8}T_ve|iX{6PmU5hQwj&iuH}U{teIYv>08d#;mC< z$Pa@Cq-EAnVAcsXxhDXPHE;~;<``Q5$C5QNmd_CgD2Q)hR)P4eiHqAqaai#En8YCn zF}LqAXIUe77f1=ZV;um^jrZsfY-Ttv$AAiXzTluEJ_dfbE5oozE&q)Letf4v z#b8boBMg}CU;;fDh?zn*LEOw(D;S66OA;djv+CjYNnuy65ja^mwj&nH(+Yg2f<nAmbjEn1+9ES~t%@!}tXb#yac))B^U5_Xuay(m)&- zLZ(6Zxv7T49vKeU!7%#_3U4*nPud32mHY;^_cKi5VZWS-T|8{FueDMTN9w#*(29)eMbNVQwmmo-p; zF^A3IoYlN>8MD()df1@^KAyjOJwo1z;~M~gqHHog#CTi}V7Ny%Y5i5u0bIn;0(SvR z`cHy|g>#1hK$Bq9;yr(|5a1mP9o8S$*!U^WD;12WXn1Dirdl~d^Dx%Q-ZqvbGAQEW z=Wa7-(=X|j6B4wvr9qFrHv!9iHEjA0y>Y%7$KE;r#8>iEQjBxm+FTEcMzEood!hxu zF6p05D@+GK>tU^4NT<-3g4VZbd20kj_8+=%eYLcPqXE)H3pv>af0$TTO zLjuX3z}ut_tntgibpSQ3$2=o(Rnnz^lDXlYKJ}s+=Ff5`b7`OTpTld+4qdVbO&IC0 z97zwxV+A;_E)T((35M0ZXKW}Fwa)!neq*vEv?9(-0>Z;dX7is#qf}v*1}#l zVQfLHZo_)JOLsW8*51xJ#X~QEd$z-(&r1PajuC$5T%(co0ZTi?r%FXWGg+>LiZCJU zJuQCh0p`le0=w=D*0UR5i$#b@%{&n;MKNceE3ocuPy&Oa40@aN)bCdcFb`pDtSbeV zwR%c#Hve`fR-i2v1Mp%Y<{JuLdyHRVWC3~*Bl8S>vK_QE4_KGOWC;(4>_M!xCaWz8 zruTU*iXpGVx`ve%T3Hx_Ob@h#xldg~6EJS74B=rM6OFe7S#j%AJ2mMr@jyU*7R<6SYOm>puZX`a;mfL8O(QAA;KSpU4mHo zX_j72d{8jT{9$@BMBRU>l?RB>PBx>z2^3!oYM!!-8)v-y5W(bMS^oDAJ5!~6{fjRv z@A{6r@><+1cetqB^KE}w{;7BGavKDQnYgut2q$u&mG_HD27InHLm)&Fib5hsbukON zj1>fRQzML+$7CEbS6XO1_Kbrmc?NR^b8aZD5kQQf5LDSbIil8R(wc(s(-j9O6~u8C z3s=axDQ$rDqn=ve-13=>oW8`>#=OvpywB{}g>;~0C6+Ou5Xmjo<$@5>1Fx-Kc7BdxGbW|W!N zdqzMq=D7hD2()dUF&0-1qzzYVT`EfV}N7X zW6Tr#aykTTAe;s0o@%hbV%UeSbw>*9Oe_)%#LX<2qz_3Pa*$lF6~ARpJpG}!bPm{v z0Jbqf`+`_At#=HG09@>04c;WY0;rHR7xDUdT!K)`Eh5>GjiGJC7|+ZoU6X?ccb zC9!sGq366+12~AcfQA7Y)V0)oDcz}Lp_!oYVCAr!ihu>$ksqv+W&|6$hI_nIQWsc} z?#qqLEPe6Z;ucy}$q=CU%qTuutdr!$yLqZ*K@J=|5B|iuLBA$&%~EG!26MBqVJ$3qP6dIf2g#Uw%%d%J&?vDo z*P6~dwG0cWy}!@7q1tSFOsuiXLa?NR$TMiQ1|`p6te&-N8I^XydBWT~_Qe zKF{WvY#5$Eg4+Qm3*a_qzEz^+4-2ipNEIeB%V~!l{rU0&fn5 zq3eHnuMKD}f}UAYtgTmFAanlT)C z7)(-kz!Gj)-DvD{n7C&tdY<4Ifna$G1+b@AjGNoWBBJ$6P|^Y}T0mY7563)@{vBaA z>~NP_$=RGxc*l~OY{S8A`8R@A9*Pj@$)I73ZseoE~2(a_I_k8bj%R9c~4dt6Cc39eT%SDTi z@NQ}YV$oE>)tXk+aDze0v>O0IHL>$n7&D@irvMrN0|L7vF=x!LEexH$>`{Xl>Wm=H(kChB3i0w?eg)(K$O zXMPAW>;rz= z%UA_vJPS*aM-w@6L2a*h4tvh)paht``_?$sk$`~bjR_sd90NRD1NRd%%2m({8F)*C zw(iJf>ob`Og(qv2%xys~%FWDdxd0)bWl0R&jetwzPx-*!v)-N|3{P-QxMzbpiF^e; z@=j=_r;BlADZcWV8d$a)_YJ1R59k3#JArq1KLzqGRVW?~Ik711;BpZtEJFjc=b_q13<| zzz0_DP~+sNP6{2%8dL^+O64CZNX#DHAZy>21T*^Wz8e5&XMmqdaNfq=)56B}iTe{Y z%lmLG=`u$JW)+Bybf2*1QCa&c>tAyNlX22mX48+~JRttIPPsC0$;I39FghMaaXBujV_ zf3fzmoSWWsbzBd~n4k^n7BZR!yAcf3*cx1BFp3(yE&Cu&45py9IIc0`MLb_ns}Me0 zD3m|$PzYAbhSrG|0W${>jI_jIy&6y|qHwmSv0pM35BTn4&Ec)axhPa|KWcI45I$<3 zK!PxIBo_D7W-XvpE9aj*YD#sSb=zXe8o?}=6qfb)kGUsLAbb@J9)5097-*YR&g3FnnuM8BcZHRUgmiNB`oaPlBI8rZ7{oWw>&V z;No#S&pKW_OL@T+9h2DCg~oqz^|6r+%v3W@jFp0g>jMe|5CEFKu{S(xj7I0Tx@>g~ z5Bh)&EO}a5jKLA0TF^J9AfJ$D$tai?K`YPFqA?(j$yIe7v_fc6-34s#?S7gNHr!-8 z%me62>qab03QwPI84CK*GN)RC`T&Lqvph#kCCHoN8pT?|>l;dfOt7fx9&{c|!m(DH zV0^N18?MzEU9AoR0nic_5?pS^V?j@5QriM>05b-JYqf2BrWPiISOhYY(_`Kj2q=cf zt${=Z zScdor1;UduSdg;Ikv6f;02Dl{HKW5?!o~G>+;;-(gd!k_*Uc-PCHt4`?TTu69hOSy z*;pzqwmmFuw#JYH0F71Dc`4u*I79V)q&u`;UHe)Wm&8h?#v|+L`s-p81Y2J%Wk3Lv zImeQ@hl|onEu(-DNn_o3w#gmVew6;x1Z4sN_V)mbWT+d^q1DSPmh1=P+MHuhCHIne z<>Jsx%+PY|oMb;jUk1mUjt z8CbrDeY49uZCXU=7BnXn5W@&S)FZIfUd`I_SxV^eJ+67Jk%B;;z!EV>ScT{CDHWtj zSXi}ivAS0_jOAn;GveMn^VJX#0p*Bmdlq%Z(rsy%IkAqmYIBnZ0=xn4mT>WU0h^~A z;FqSe0w^v)nQZ0D@Iw{rA!Ap;<1fa+e&zjK#3z-P_36hzErc>ehLphOlIX_Znff{p zGuJuKa30_Yv6k~Yd~e46-TW%%k9ljZE$XQAgipXnU2jTbXwe-~c>sn0nOMXLfOm>y z$eVxldr(%HA>PZtZWS^_D|F&H*$OTEz>p#1xbewnA2<_H_?hQ@8R9-UjbsRW`ed3? z_LQ}QFiQpE{Ccc(x^vuJnCfM4aA1HHmJ8~IS#wIu*vKP#V59}hL!Y2zL4yowiV*L~ zU1_oogOn|1JTP7afilOU*7teF?#a}wly1D)mN9(X!T)A=5%!DwOqU{j3IVjvhLh2I z)XxZujID$DDb#fxSsSS91Nitpv1VxCaV?@j$1O;Imk1Vb5iD8=+3ZS%lC|>;aK=Cw zmzhWJXbqdqK285O5@7FVEpayrLZk-Y;nG={#Boe}yLFK@l;Gl(7G zy$(bsjC9dOU1RI&7{YS-dPdN89|3NmWKW1tw17OTP~&+DRNc4&x*iq(IWr4jAP_(V zA%u-P>@d4U0AV@N4ZZ+`3;;q%Lk4X@Tjm#OZG4d_i@KHv1X8zHSJlvaSSl?gY%E?* zYM5Z#1laKb?_<6IFIt)C4$rItCDsz&ZL$RmK|dz|02BZ&QK%0$1$uR!h}PkEg&gr? z_Lu9Sj0)TZ^3X}*p#U-Vu?3`S*~)QsTt8&qdltWCKDB7*j8e1}kLuCAq)^t9;b(kn zd|S(S=LpQ6>x`i73jh#I_C#TyEJ1!cR{<;nhh%zV!QvSWhsyUj4MX~l3l^nhj|33s zafdZEb}mN`3E4<40`jvyJ=}T5sWQGX0ub5?Tm$gfvjGA4dmewJ@J6^UvD%eA;>@s^ z#Y)HD5R9GUZ(`aQdxR-qKpbKOr52Mt-aY32mVKBa*HFz8D?7vqtqW42V=TOVthoa1 zF~C$o?8zB(Ywa;7u_kGqg{~HiO*icxd%ca7*PUHK!JzLr=sQ*gX`?1Ev3AhK!Z68Mp|=6cm61A*o6(2+o(zwRHAyx4X7X1JB?Z!J(iVn)KhO-+*N3L*7D+s*drv zx>Ziv^SFZd0Gj8}y!R&i*cY7s( zTuiU3j4^>Kun3t2mHB{rnG=2mXh%%I{wFgmP}qGYdQA{aSAL zUEe1b4g0<%=15DFeduv~Rkg_p;)t}O=RcQH!7C{hf57?4Em{h;5md8kI!>+X?B8U-oJeZ%vPjQtX%Oj4ozJLb!4#1KO zO4kHoD-ggcXcL&35v%LVxS@_9^${^k2Bx9X0MJi*nciezZU~ea69l4y^;eb^YyehU4%c z6TttiiiaKp=F|92!C`MzN{E}7v#L}Ga2O>s1}!s3W~`1`V?zdPuDyRV*jV(|v71^% zb?sXAh}|Lr0+<1in4Se?QKne6yo=uRlfJVjmw@yRVBL~=tSfbogbZU^hgyBLXk*>e z^|_-3)Tu-1)qAnW9<)%9bZXtu7J#|MGe(46SXkInDRRp`@mVSOZrn1Ke`6Xgo7A`1 zvOA080Zm4+>5p(^30dG@0^I73b=+7EqdchiXb+*m%grrHi6B89^HH;VJv^P~vd>d4 zCe~W^o*DFfp5xe{fqfZr;xa_pV(h5$Qg?g|_0l{PWyJu0Zj4+MR|wh-Pv-Z18S?*s z8RC9CiPpUH(o0ty_$2OL-SX0xy{z2+4(FF=Kl@oQN&?*jF$5NDShP&IQDuJ$Wd&}& zm(Yl7BhJIPDH*u&O)2SMWo=FM2sVL{^anT1PfJ%=Z!IoIgvt`()58k5i}W%B&S^04 zd5Hj2i00s3K9ji3$Xyasx5Sl^`fv12c36uG!U$n33Lv3`!QNVf^it^-uB8_2KMiKt zAzZl%hK4YPu_|PdYxAX++OH1Js- zvI+%p3lt5FwF2&4Xg+SfSgYJaHpk4`2mleN9+?)4D4*)q&4~;M-aV|&IZKv}H`0HSYoI-qF2SrcxK8>p4$Y&! z49`eX2jD>-u`t$;ecz$v8I$WUN>i;?f{%{tJeh%&bJYPit`gjXc`;kuq^v%4W5Mzq znC_PVV2hb=5YJdMf+ctyl~}z6$-Ef8qGgM@B@WF*4NLxb9`4ADPQPE#fpK(Z>ZT^8 zAf3IUGa(8>tW|(ZglLpRfOR*;rHxf;1MuWp@!(`!yKCrS<~F)4{Laku+5nC4q^&I! zq6u@tJWSywp3oxrH@w8UiYhQn4j>jj!>^u-Q_<6Ex0>YS_!R7@44$-6%o>LVv!cwi zEtWE^tkArxG+^x(JX0&Jv%7j)_JCGINz(gWXU8DVO#&LU8~P5v0c_IOrEXy88|K1Z zCI?}rmUNEE{~Ac zD4+Iah*W<1$&f2Qb^S>dF+OGB?hdyO? zW@z6NgqsS#ab=sjtm3+ZK3DDr&*Zdjk`-4MFm5xlYB0ZqE8D?hfJ@2XUx8GkK*!~v z#%u(EZ5C1@KECW+|xt*WdX z{QI9LvjIx{(v6NlI8-;#Z&hVJ!#$pJo!P$#b!My0B=eCY& zEb4aM{NonojL{6BMr`YMfK4mwjixM_xfz2qW3e{cv-THl%P=F8U8L}6Cr@cT(!1#)?dj}MOfUYQ zWH10|G*`{L`L~ucziHQ8Gr9CI$4qAVI;Hh3zgnf5@@*TSCF<|Yd>!DJAOib5K$WlH z6uz|vxjvi$&Q<%!qccHgZVteBpr2`28jZ>Ho)~f;ECAZPjj&-qWy%9&-d$g0Y5+A5 z6Ie{U@&Qu3tW?er~skEZyY-|jHgjZU`gFUm?&(7M_9xh?>RHiXsxlpwA z@;NI-PJ7}^>$ta9uINoqzPD&e;PjmaGl8r&d&$q{H%%yGs=$QB)P4jA%ahren54k2 zOE5@Nx00@BKwS^f=DfJKsMZOD>Acc_St^}N0P9W5*_?<*=dO}vYrr_a!-*<4KM{913K%gv%fL+**~m0t8yad z7pC92rmV|zcuT3XL~?)fkUxcom~yRs^~pp2|IR~x`Cq^M`N7@a{r$h0Ej3YwNstIl z()Xl1@XZ=wzGi~J1V?LwF|Q7#A>ez1xaH7WjN9!Y%mUQ+X$X9f$*@SRG*uD8Hw3J- z5T#C-Xt6;yr0}!=b45(1XVIWUREi8GLH4W-=2V{|r(c*KGC$@+lz-3_s95PwZ5)#k zwv27H{7BL={-H&h11R;WgVf&(;az_A_mJ-))G^y_389AbFVDQtnB)+?%S16?649hl z%;zmhtamSr-h3ja`M801SWQ|qkJn~KsIy+pjVYT}v{az(;+`uodBg!(9XD(rH+(`48~5muk5RteBo(1Df8OJHp0urWymFGx^I@8z>;-grROS zceyov&;UUzn~xI?@9#{5fdc?JlbqHWn%(vN-#{DnQlHmK(AnBz(UgK5_Vp{L`!T!O zb7M}`ud09)?V4t1*{$xUg;_BT<`;ON6{>D%ZRU373%E6&tMk!k`Il|d0ufBM%$V~I zpBH#E?;R~yuXMHm%M}orR=h3UJBmuJ1?-MY#E%E_+dTUIb@dg11FX!&W@R4i)z10! zXiWTk>Fz060Mb{4LvOwS05SQCAMf3yrqjXg&e*n^3u!{M}bB7_?%9ngF_U z@J2Jb2j)I#pdQh%%!~IniBRp4W$n#t^F!lXWNaY&18^N@4;nHkZR-BE4qpf*1pozn z*J;@kEOHO%OnB!9P&d)<-gO3EkAy2~G504RwMPU0%h=MC=0BI5xUrXNnWTH}#aK@A zQ5L;D{-9|O-4|t@6fXW+=t48vxUC~l7cFST3xZnS=f|y$ON{jhSewKd!&H;0KaCw- zEed^tih#JgP#MUJHl58&mXe{*Lp#kg5Soxw`{W@r3;t>Dms2_Qi9dPB|8hL!*T4RU z9|i7)KDLd1injPtAvzdFCd-J^Bu4e{Q432?G3g)J76velc_Onb^OXPL6yG22w)2T8 zW&wzR0ckqljEHNccOLz{_II9G3gmDIMyO~|k|YB|IZ!9rZ%UquSnj3>`|X%yX2SR~ z|GXSB35n?oh)f{ILM#_Qr_9NZ4_|2Ho)E0^^j)Ex0aJ)*K?b9lLmH21=S1a|C+yYl zwI>Yi0|6W<*}KMMHU!P+pp`|d!>l}#J7S2_%?tpeF8}eNh}fc5#0A9bQIP_VZt0I`tn@5xshf ztG5Q)Fg^FCCC$f-+m3axmabo8;?2=$c*+Nc;RSqaF{9Y%B%XDB+S7{!)uS=7pJM4J z{mDet8s!(X#pqw9?|5c5YJT%UEZOViy`!nySE%b1f08~{o!1Lr;3eCxRznw^qmD`;hm3ph@D76mix*nwz;SllRlrdCCAQAlC+&{iXxq>!`SzCG;zKQe zy?|7Sj#u_~k*pt?RPEE6*_SI(c`QLFmx2zS`Rb;jL)WgI`P&%VE6051d~)sF5-^5F znaPX3l!c(k=gz^>fK7c`p`|M{r`Z{8Vv&{RC4r~ZC!Nhh`_i~sbI~bl<{Dn4%>>Iu zKC{-!CutTJv%H5jc0PV%RrxAM<72&9S}qAE^IA{N{0K{EycWQ=_^jUjalP!5hs=b1 z@{ms+ayvRd_{UEQ?uvekHN}vfP6Q)*!$Y3-1E zQCj)3V(2{MW6*(8t$J|VB=s$M^pfZb+Ub`;oU8k8w^pKxb`KGFSyTiPfZV3NWShT$7g5BA$Vmi1tNjYs1*z0A%L5_uq?R#Lx;JS;`!_ z&^qM{*LZ>&^9!~8(_8HGs$h(O<#eModnyL zM;c`eyL?e6z`h`%9LX!I7G{d!t$@Zf!_}}oVMt5W2SY2ud)C%^_iN2qCv}TGRrP>C zNo$a+!X)o@NqO?NX;TS8V4=+fSUFcEc>WF}eYrlnK39XrKvQdeaz!ZpO3ZYk;Q;tv zSqZJ8Irq-T2oj@7@`ZKIXY^7k3TwJnrs>_!1hB-J%-4aH@-R;6G<$wDz}D{yB&?(i z3V5VeD>3hA7v0h9Pf5XqHbT}DfSgvo9E4|c+{&&e4`0u>4<<^pJrU?B6;65G1nxB7 zV-hz?U3@HB@j+Oz;0)tR+nX1B*|IZvSx zGlDeeTalF$d|*Eo>{H$7a`dg)zteaHT1p7r>1yA#)+JZ|>e&O%I)f8EfNu26asvj? z>OxuV;S|<3vJv6qe~xEV$_J(mZrrw{)f?z znE=D1jXBY1jL8IJ{z!Wfk=Mua+eK_of)Tc3%8@Rh+;9L#RS8Zi6_hd~X?Xn38kD~m zU$kZV({2_7(fco75ZuRCk-kh(B01kM?EHT+>z$b$18_ynnHcu~2_6?Sp1Q1vXT-Xk zU-{C_@A9$~`FT2J;;GN(g?YCAtjuj1ys0&b*q;L})+ztQ3x-tP+svJ7V}DIsX#Vna zx?(WmxpY>#WFW7)h0nmug@2>L0jIvA9odVP4M1m#sj5Vpm9?CAC+5`^2C{hq{6wP; zIAQ8tLOo-^`WV1qUOLc7Tml}}_=*9pGWofGPKmT4`^pR~s1m=22v; z-nJiNVEY103igOGj;Sz!V!d-_t9kArz?OD7jhneR0v_Y%SCZVcA;U<`v+=Zdt7@_} z*8M!MC`1}7U~^1|1e~v;a!cC$X8%8W=8|aJSqMxR#G`A5=^67ijVjR5Dwe0}q;L5} zwYByS|J;Y~AQ#38l9h3PyKh~KkHsEsj z6-dyID%ilRyAG(r=-Y5Blokuj(D&J{hg|_?}9QvZkS{ zJYSL8UzJ*$=;Ia-0Q*44^5HB8q@8Zg67cM;c@V(v{q4i*K5y*vH26z8l`iOS0v>u{ zHl-RN%sDF;&&UNJU)btU*D8sU{J1XqlVYP66ph=@e67;3O&B?9IZn>_M1&B@ z>xyAm`R-H@yn3x@}>EaO<6Gvv)pvupQ#XcoO=TqCCt6*Ly4ua2;VL#N@8r?axXCi71IJO zd9|L>eqfAOCd;#`3aVYnjg{n2s!Uk`ETrK%2ad=8r`I9OPx;YdEdB~K`os9^CCET? z5ZEpkTYDtUV)tyAxk?eSC90gQb+thYf;m(i-IiEyq~wtFG=>!byN<7&FPK(K%~HQJ z5x<%1DjMW4o?j6*g@IUq;QgJ6dMo+vq`3h`0~WQkr1R5$tPEax)n3*=TOu$;1s@fV z-8TypQ(F)aYVd4YrqCwdiRP0 z;o|z8Xmq_l@FkuGxIagi<}5DcHqCDpd>UsmY(F2<6aqjCwDwGUIFo1lWX?x_+Y_0_ zzvFxNjnTgrk*ckto!Yf2~wn{D;c2-9r zSA|}=LZ`xh7iZr|wvGo&SbsA40=6`!*Uews4?$UU$+HW*XumJ60>g>EP_=bt>pM11m)PabmTA#*Z*_&=+kDiuo6vVZq?|2Kw9 z+Gdu#w>hZeV}oc&@_Cg*?DZ8RaL^C@zyd1~tY};&nC<4T20X0!>Xf_Z9|tfLtw#G$ zS`F<~`6)Evs^k<-6A+ZE75jlL%w3+eDlfe{#3{#tR@sXo#3Zsx27RRjWV zK*e_hSZ+VZNk8U_;7tT60I`zYUb3%;i^Vg zoR+7kx!xbZJvTS*nW_ffUR!|Y{N}QxanEw?fJN^rZ33#`^zL-HKuG!`7eD0 zQq32wO(wOgFzAyxNJ<}TX~WeveOJ$XKE6`sV$vU^onew2P%xSokJir>ZNN3gktRwT zr+VrgP|xo(!eyMEx3n}9<`dJYhV3v_nla74y`9Nm_|C!BshEneOe(G`qL2?S_fGZGWvKhyB1TCsj^Q_gT@OS*LoQ z7x+E17-pA%LE|?jwb9@O63uJ-A#fE)XuS+I4Q>FX$m#ojP1RDZ&H@_(u4%*W4)^sj z?N8@n_F{sEHO=MV1E>j#UYc*$6mX;`u1#x{Z{`9z#(&j3)RHL2>D|~SMbBK%IyaUrgl9=K?~yZ?ocChw*0sE^+S4Tr8#2EKeZOnJZOM)i2VHzo`ZN1VDWNc3Wc$ zG_UN(OUcGtT&U`rR><>4sMMQMr7S@wt^vG{_I?#%nzM$yG@=*aZpA;6nwnb% zbENSF)AMgEyes#Da=_JQPMZsTEM-Y<0D)3>du!u}mYH)jWqFU^n_Kg0Q3g;2j$Z{h zl}z}>c{P&{?*yE0?6Uw`<uMu}1 ztyPs^Iu{AAXzS>4LbuFuUS<{xSg92at9M$g0E76!d|BuFoY9 z?t96MU6)^6MZ5cCQg#3*YZ|`VfQ4!|GINxzJw{skg?rAbB+4rQDdx?!<-kg7gq{Zo zFqDW?`i%0pjo(T@W{7H_h$dl@;4bVg2e!!Dm`I1qH`B;X384lT6YU_Ut*$cY9>++k!02gW6^_YFhR7+agI4TBy1RAE16fNuqy&O^`miPpfT&$Srdt40m@AbcMwuzb_r&8qAA$Y3?6|7L8#b06CCie z1F|mwf621*NjsIM0fVppN_7 z9#X^9q>pxT@|Su4!QKf{yeY+(r_(&sHLpMl9hxr1lyeaP2+VH)J%6$ye`ntVqP4aC zQqW3n5@}vLA5+)5AAGAwp!wz!QHKzw_osvsJ6n_JWxe^%1 zXe*JH?bFYVt@+HqvRlm6jLLq{tF?3I$$q!?0P{sZCRNDkw*!=R{6}}z*CLru>!&}> zLQmOw;GEAlf4xYV<4mSeOVD_JZr?3$+M3f5etNHQ*hYF|9Z$>m34@g|Ot2}z^$V@@ z!%O>!ublI?aVGN{4a=!aXdNtjt_(d+pUMeXThZblnBqHEX$Y?2Bw;5p9{1lXOMnguZx&CJSS)bhhh%QC9J6i>HL{n>@Jmiyy zeDaWg%tMxw@x%YUQJ)`v<3D)^2JtGJ{nL))If}8ubaHxLa!;ihAbBE6TlFmSqbbR1 zhj~X5jo@qmwi0w61SaIm6O()Myd1;dnBUH%)`Qxw568!cSH3q%c`xo=7-7$J&8UfT z_(!u4HT2&*5ZfD|tD-|10pcV=9}7g;G7|)P8kGLI!2QS|!t}6~_&5g33_L88_NP7u z&PE#(SV)VL;;2pJ0k7==1Nf6YvnS^{Af5z}Ita2u@J?)gYJL<>TycaE-7BX$& za5;Bu0(S170M|)>Vf@x`qk>4Fsuc&z{Y*Q<6(9&@4%a|!P^zsmzH%P<_Vph`;l@DI z=A=CY_?gc$GoLf5>tAVSRzOmKdrgB?)aVglU8-!PwOyEJX1IX;XxdDBCcWyT)=D9= z#mGaHnPsbp@+7!q>e1>)n#1um#qa~_X@lDTtwB{U(w6l500!Wz0Guh~W%^5ITUD5q zvv#G0JT}MqyJEmarXJcvw9*?sdzHWn6YZ+NLSySRcyuQz|G>Ptd-!YPzNf@U6AYvoNB(5_=f2qokF=X| zZUyN=Yx;qHw)T?{*%?c)E_KsYTAZ!(mr(O&oB_K^VHL5QU*`!}EVyoimgH~RWPS3G zX8n_geDaWmheX4FO#5lU9Y!C6FDmdvOSC}{SNwzW6}zU5@V{q-IrE#->@Q@c3N$Vj^V4w(4{SOBz;Yyc}WZXj;-keHaD0TH=@ z#|qP*y>KF3Fxnlbo<=!!EgMjNHMARBjOzIYRHidyYKjROE5>Soh#ycxGr1L!mOozv zJHNeiAjou$qjjRbh7V6#0_@SeH2=$HnBw%9%s%s#Z-xjbwVQKOV-C97%>a;p>>(?} zY;K|+UJ&0vMRS%`B0r}y&0_vxdC@%zJV|?b1h_ZmvTL4Pn}1l0BPLO5l^E_Y1kuI; z?$*1vErrJYDTi4fryYn-Mcl8z$~i6Sjde^EY(vPjdd;+|NYn2{5$kFm0FU2d9BwX( zxUyI;knN0_#&JIpf<}(9Wr}VM(^{PZOZ=)5a7*O; zQX<&f8F-`39s$VTtz4ir6JdUAIyCoR+wcB&v{&{M2o$TmM=Ba-fTOdeuO}L;S$Ee% zMgyh~{3rvbfr)qXaBv2S2A@{oLK>ykbUthU>ql?YnY2Wcvcvq^efBh8vxI;f9N0;D zvRM)u0#EtS+RJJ62vk=lxl)VFHfcT!(0K!n)7IHb<&C35_S}L}@&oKrXAiJ_6pZDN zTN~%kQ2gIorl~T6`ONX*>U;$x1B69~z5!8tYn;>mqyPc3@+ZAWa}$)wBwuN>fLwDU ze%WslyEw0<5^8^z?-23wwSI|iE(qmu{6aHDX4bAhU{T|OR`;}!7uw|#QJ-n;GJ8+i zL{Bpk+r0dDW*!aO3pg-A##AJ}yx z36~>mg+|nGjk|(&wq4oUmn9qRp}!6j+xc@v-l;F?{0zJ@3wd5`3D& z`b>TGKOKJj?>X8qOvm)FX%1#`Iu5p}>5ik@^f9Jm`W)RI!#PYFCXcR7Z#bCl=K6l_ z<9i?XZ+QRkem(o-e@M~)xlS>O;c_Re_xg7!Qa-^CJ`cnyG>MjeWr~&^su1j&C-tT( zbr2aAeE4-YClX+Us$Ybxxd`D((8f$-&P7~3J_rm3dnOcsKied zxIvUyWEAL^7uNeGzp(x3`ndbAVobqvyGok%Dqyv_BUP3lED`$?Z&YpWcD}vsqfO(A^PQR7U!1PG z=nhQ};SN(E(}STVA~EXEKAQ=2xIHz3n}(&23}9R#3|cv7SOvDgn!t1S zk1f5aB5{mb+wTPDn&@Z`Xg}txVvjY~5-rUDZqJnr>OsRuo%!y7m%y}Fa_e++x1gKk z8zK_@;%#5-r}&ha?ybeyU1bMe4wzheC4&V_381ND7}eG*_ZGIU$`7jm70YALy@A0W z>Q#VhV8$an4woX{N}FV1d@G6>qKK21({x)bpFEajb9_ptgWqMLfQL=z3>bMU#w-fT zx=Iu-dE}~BnrR0_`tj7^YuEdn7JlV?2GVv4r3Nwmew$in8c2;D+|@;?f&Rv{K_3Ce zNqK*tz!fZ!-6d2!Jm{ozC%dX2aOjSXvFE7}q7{HZ`wlAKM=x?0$1NeTW#1HfEN2z_ z4(=7TNBDTqLpM9>VjJIw)vhDuQYg4hm|1_32<-;p;vF521 z+Av>ac(t0X-Bj~M4XS%@;d~IbVf;qu{ZQI}O2h8>IufFjRNEzP43v$%^u!=)A49fWY%0fr|*HiEHrdOnIbBq4mrce&@K9sBgX$cYs zL~RwcE?jSUEPBEy?^u?Wqdpomt?w1|2riL#ue`Vd@pN*7IeApxTZ^q|dYE>|@=kAp zgsF2nRe23p8WBE9u@!7xO3;0PL|f71@#!|7gSJDGHhl>7u?} zyOQ*$jtSbe>zV|Jh_-@9mkOpTxe97Q30zl*X;VURk1VMwWfG#T1qpP+=@v; ztCp(bpLlImYU0PI>97ylO@pTN1^w%mVTFZj8<=%ir*?%>X2aUi(2}d)f4DSEW&2&c%7k=t0o%F9I{=0vl=dw2txa{i}mG@ zF0dEJ{4b@vDuYT)PyUg~$RcA0M~Gy!=ZM7fN?7~JzTetFbbAhn?M0~i!>sV^;w{s2 zAP9qR%<=|LHE-6 z^BTPGdbj5{tf}R0TmPQVqiy!9DJ5{o_A-}v6ga0#QV~=`@CZA82;_0lh6%D z6t>yt;;L;LA~=~w*P@E~snz^uY?Gj+0jP9u(>uE1Zr``$H_aud^Guz9F75jBi?2|# z9r13Bn{FYRxa|JZ5Xjv#-nb7d>22=KhU5}yHcKavd})msMaP@dF%*}YEUo{}2Ree! z4yBYXV_UnwB4X4qpiim!LgYs4-a3u9CXXGT$5vPu>}RD{=e=px1Z-4=YOaV4I4fyY zK7>5rY|oGET5h5Ycz&1#cA&;Zjlhm;NBP5|!aV*4n}}*`K8m)W$;2V752a&68W0*e zNz8x)9m|*4Ap>UxBLZQhD9_o3adeoe$L*jT_?UwjZhSE)H<|PBU6=ifbo)}yd)lx9 z0*<5_`Hm2p`S_xJ^-22fG=5VVd9Y}3K9Y0z7KRS61Z;IB@m2R0qX-3BD+sHu3aU5E z3{Ffl#{`U-JLBM@9>TKu$GQolDj_$4ul_E2jDe8%;6K%T6P8 z?-+rJAmJKGrx}2XLD{n@Mc639q}IJ`J^iEom&q57A&(JzP)uJuuH~Rldo5DauhV8f z5w|vM3Li%c7@~L<#b-dKH`qY!VbhSjn(9@;S5h%g3JC1oCCK|F5$THk@$(owDxdg5 zcKABA)tG#rXQm zh{?YHVFsQ8$3@wl&^qepU)l-mIwvoSn*TBj`|r;{PiO+|Yq1j{kS6SsJWMq#zKI{c zoq%5<-8J~(rCv4YZTZV<^4qMj>%D|RkC>sXqOQKSVILy?Poh+n3BhLjG2yRmLB$JB zL9RKD>L)*ltgz;Jp&A*yEi%+4Zl8Mh=${U_FM#Q0XdE(G=s2t@dk{~-;66ED-0W@e!6wm)$?2N!O~XWmF6-@gTa9c^M+Dv7aMK~@J9|yMVchd2 zp=@3=XW)&Jta7Nht3eo4u%HwYsv92YYzhFl4l3cJ(PQVe22NsT~Dd zjH+jV#m_&xa`PyTOZo?CfFo2|O^eOUo-Iu5g69EuWqe41P{nLZFdl{S<+ne0?P*LO zBj{NOBS1#ercR}cvKr$nn&2>@!Nwbe~GZg&WC^%0Jp*4d29fKa~WYa_VA@gO!x}9Tm2B>~orbzFdLNkbP{4^o)ceEyetx*udZi(==m?ZW%kkc#PC81P~0`=&?ZD*;#0 z%WAPVldt-6RST2#k9YLe>Yr}N#BR4A)eW<0`(p*s;?DHI`k!Iuq)HG}*~)@@sNONI zS}*sr+0j~B06Spk;cu$f=M94rudLyt6T5rBu%Em1!%YbQ^R0n2?+{Stl z{-NTDPeA{LX&Z$c91UPuK)=b=Xx#Suqzz+ycU)}@r5b50Sv#nQcQE$4JBs+UisOCl zrq!G2p)auJs=&Kq(_K*2|f%Dl*4(Pov`mEv= zQDc@4)i{U$2I+?m>K$BO8!Cuxx@08mCS?qqgp`!tZZ7I9C{Ny?=BkZJU{`qD_Me(~ z#`T>dUhBn;bSMiUF;HHPGLY?%XMZQ{ObN*O8OIQgdbWJkkoguOArIQkSJs|3CoZU- zh6g^+9$$>Zso@P`U#q_oDU?M4(K!!xQjZf6*D@J_CKW|QAuLWOeYZJYuc2<>Z_V&$ zQM~F$r$pi#{#K zO&zd4d5QkUz|^7WG0|X5yREmWW6RMoU?k!9K$SQ5_fx$`R>|W0`iuEH1puS`gR}Gb zZw-0&Um(})0}hW9bQQZ4vTrZ+%)cY%yxn$#1EvF*a6|gw1e3Ta++0H*9 zGwVu-4f(rBx`%SZp)&*hviHrbTN_Q?s+*HZGm4)m^#!*D8xnY82M~#v9<^OPChpUz z+Rv{V)zh3~oBkfJ5qMylshJ;t36VEDUlH7}P|lpN*ucjw`(A7JL$Vy%X2N*&I?+lL z&_($zhD6gks*547{_ifGkn|Kuie+Wlf(-b>C3fgjXwi$esSNiwJGJY@1pLG+0L_fIgoK#%(o$D{ z`>G;Ht6`#4xv2=#>-PI*sdbJEAz%!f_1$YfpAR?d&6l1jJDk6S zp)5G>Ef?g3&4ZVer-c6YBc=^J-hZ=Fs^q7`{nRn~^6r-YQ&$xpHV)n@cEymwxpl$o zi#Y79AVSZmJ_i>aE)k)nOa}~ACECB>D~P_Jk2K&*UFRRfhgR-;$7;;v)VnE@H`#dP z)Yh%XVfi{G)h#_*o_AFY0^_bfwDqo(EWV$04l!Qp3$6ZU$EMc*hrKfc_z;*q-#4PG zC_Z0Wf4p<^vvsmWqH#dj$i&ifNqe$z0J){*2L zQNibBSS}WI_b!fEMeMKLG~jQj39V@+=g4`@Diu?$S%poo2gc{iE2rX_mt$)L*Bef{ z^=5=E78#Alo02Jr`OD)}u$tZc>Crhu?wCD>cMM62i9mbKeTh>nZ@s~KXlor#@lS|` z|3mTxBHpw)py+vR#gOro-tRVgCf=~0h(ovs+3k6s*9-F51PvJ*1% zt(s}wSE4LZS%<@e7Z=?ptZR=Noj{LW~46(PT7wRn@`Qh4cVs z8}>Tl{>WDC_#sDtwE*<)O3eC6{B6(*Ag8s*lTC7DdL1n*k-7HbU!9m8II{g}=mOnE z=>Hz)rPIIH`=V)?Y=Nmy3eBi}KAE6OaHy9+D%A?ld^eIT_#xzJvn_t3{Q9w1HRgxb zH(jgz+`Y>|_~Y?7EXh3MdNoM;34#HYWSyEiklR}4Ml#|f-0ft7;Cpq*gx-p@4({C4 ze$b~8^G-f%_%2Ow=}1qvE#ui$n)jK3w(SkM;HTl~mDx79K1Y**{EBA#tIcjvGoq{h z*Haxix9!;fqF0?Ybq+3421$S6y_-XM_XyY)cy?;3W0~gEO@`f}l7hlsV-;SY{Tvr5qpg9AhMa9ws$)yDOD^}rRlYS^8Z#VX z=`n{#NC|1BZW7w5$at&E&Q8-$^Do0F0A!|kwUejrPO zOKDqkHJzOJZHor$zbXnWQZbcGNpFv?mQC9v%}<5*p21SiIZ8J=+?%^JYx^i}hR=|d zD)<4$N_HXCwq!44@mww~5K`9CG8CV-uT2i>V&o5IaRe>9hm2C-Gfe@? z5PDl^@sKn8OGl?COezF9{O{>_^avz_F(xD<^o4zrK>gNO1EuvvlgasA`m`b8VuAUR zp0##!@g%NTWfw9ha9!8o&3gK*!eY&sgI!+TH0y^({P~+7+l{gYZ>Sc)eM<(-dAHsi z9&hgFSYe=WkPjkmVqk%qR;hdO3A8<)rxkwxKi^wX_R*l+U*=%hXKMpzx$|kZY+@Wi z&%Zcr3?pCsamu-LI2Fh6?7f_Y_wxTDQ%Aiq+YA;!?x{_>qh5~pI3_;mJi8_0-W_fz zQdgFqGPWrxFlXg{kstUqOr+PxX108zmGqmqj@5HJ?l@JOe3Zq(bwdyJ^687@l?Xgh z(Jjp|^@^lOVb_KXXtX=poU>IgmNEa__YA@{tkY`(ZW^uP8Yz5O0IZ4zz)PrxrQzqQ zem4U5?7^1>c724D{_=I;Yq)NVRh8lv4(kAqKa8d%9a06t;b~-0u0C357Af63V(tYs z!KNjj@iKPS!pzXsb>)6q^R1|Mom1t7ZvuRLzA2igd`kpEZo*up4BR&Q>p8@+9zZIW zgU+1Mbi(gtgD9uOOX$9CjZm@${$lc=dgb9Yl>=CZUHMl;OxmrY$_5mv5nc{k z?FcC@Qdy4J-Is$n0Li0dLi%Z5kPbEi_WFXmTb;BZojT)T&cc1?=&XSfWGS%aezf88 zI>@B&Qd{b06qxAJ#^ye}q||o3&+Gv6(*o2ZcA3^GyAuFYn2X9{LD773e>t9aWK}Wi z@^OCdD#^FT>p;6?L51r%$;T7;r$SDS5vZHEex2_*if9ovrlu%r#Z?^YR43?&7Ni;zFF(NQ|xPuChQ zLf(sBj|rpiGt#oV^j@|UX1V#VN)pIIoV<a&Jpms=LRTz#g6_w zv3Sz4=FxQ1x3Xn&(lENw-SG={^5RYNsl+I0i{GAvLv|=>R>(EMAIECV8@s&yRE*6x z=$ldCa1TIJi`sZ<>G#6MnTIn2HsDGz*pD}w3}@|NMl494EB?G^`PLS@`O`yGYoE}M z&E7!kn0p-}8-ia{@7}i-R4UzA9aK^5P6TRHUV-%R6DLxaQz>gpH04Z3)F>eTS1nj) zet<=A<8DMeEIg8Y1{vvt!W)nTJX3{%u@?afulux9uE_F+iEHgTg>C)Am9XTkoF0(|giCq@(n(wwNg51qZ783?d|6oP`F&HC zPkuZBGjV<7=3qbX-OhM|rS8#ART7nP`XtATcl^(6QZ%Oi)iQZhW6e{$XM#4O>_bft zB7i+#)Eh}$4-(ahuTYzax(KHd?9XC)A+KgAJy(LU+^bS>%$?iN3n!sOZm z9FKLJR32y>#9K%|!UFYVb2{(|F25KNA1BkIwD_lsXBc%t)^8fPo#GuM!g z-hLZ6Kjs|~_qeljjQyej=~?H(jZv8k51~4s8q8iRa3Ii(1&-ltYswC?auD-ZGDrev z7t3?vJJP1gkRrj~7wH5I?{@#3%4Y(&(p~F zg?>M5J^7|NgOzf2YdPPI;ed$3IEU)YkAYaTR!X%E@~H6)HXLwL91T%jnRmKj9vE_G z-k1S5Nh=rzTmT;C7eu3WmlD!K8+K;wP^PA^Tf@B>ZQ*(MS;>VC<8!Fb*3MbfcR`N{ z`o<0^q0Xy`RBxM}*euF_6G7j9^)hC)Ho_I|_yCN`yA8>Kod;soXHZ%HfgnOWcDonU zHZ_{9cgz`ne*^GT#Jlwq+d_7*vJl1!!NK&wJfo50*gw$+l^KSN1Q;1GlzKliKtP$S%{=sc(xV?}r=7EMxosFTHJLr2mf^v_Z?A!KR*8eq; zrKlstiLdtOhF7EyS4LLu_g3!jh}$-UTW&jV(;tox8#*u1e@q`LgN32ygE8nlmH?`4 zrjl3C(C3o-0NW?8+WUFq;v(B4O@m%;XwptS3->L4uN=Mbl|_w-7Sr@CfDum_<)s;I z;`aABhb@-BD=vP0G+?bvtvfeKH~;kkA-y%jXW}E)dFJ2*PdYp0wa`x-3bvHk*a6{} zN{@S<=dl75=3#0KNR)Gc5;UwYxlpX)z(;eZr4C zkq91Es+FQ!KCS)KN1QPzdgep7g1;5Zgf128N^4{qQKQW$;OnmfXP90|*!cY<|H9rn zCoJH?x%!WW&L9M!#$@xs9u}dRxLuIDF|iZ7?R}*Hv$r4B@FKi=Xr?0TQrHU-0GV2O;gN zoF@f;PrZCOdkv#>-7u!Q`7Ri6FTn0U@#bIt#?ah!3WyQvsHmdRK(#3#;bUA zIa3@ZJDE4$A5@!&*v+Nya-~1m?J|vrX^-1kaLHmB*q#E0I2wM&ic1Y#6ob_E7HMA7 zxNZ|#-y0YI#<)LzL3mpPxiet%wq1M>0T!HRCmOAf5=>(=aZn_tw~3GGU3hjV#w@pd zI{PpsnqO6-6$CHpzD3rccCkGN23|wig-#@r!}(UKXoOZN%C7mteeP(a6}yX@KIPm< z77A?YeTSJWs1Yz_-`_i@*pYLH@E3VnrV!QinSqKL|$61|zed|~6 zqR6^;25Fv@C_%QqnZi#K;#(%Ww0|zRF}I^L*hNNp3b9{)*0?h}zwQ*>ah6r_8C=s^ z5_7Pl*L|kbZAInV;iZCyFH^vp8Mb+iE5R6p#Q}4NOiTEkS=fv_+IcT}(9n3U_`@4N`+pJNmxzEsIp9n0K1q!B>r#W2y9A!J zqh#b4F;;oIKL0TK6COqyNh-z2*I40ijw1WCO=aXTTvg6^jUtH(D6*S*{}sBiEtk16 zr@S8z*-XvF|Dn7<_J;^7<-vZ?{y@_P>Qnw$nMxiK8HvR%f&yB9?PRH+1L1`*_6jhz zCwo4j3Q`xphqkv;$}R2Ng@;E9?Ex8scXdvoz$`5DB2oj)aNr!zs&?dRyzXB!a4q=L z#WO=bP1q}$mOuWlgF>O~VWDMr*!((dTVpDJfmpTLK@g?mT)Y-2&EEiX4TfZOwBx!L zxKy&oG{!d>Yb5OW@wml($Iygu>!|jVjo-#p&p=CIa=PP;WeMVEgcN|~`2+~(95CZ$HOs5foCw^JWj3iXp!P1 z14HY6G=p9V&p^N3gbD29TCeO$v%$Zdl_QZ4n7gj9rj&ujwGCv1|ph z+TCWRli4wc4vp#r0jsns4CQje$ts4TWg1hSlR&?Q{+ts@u(DtT%Sd&Y@X_?wx2z26 z#mK{(`9*Am*YL_-Zt+HIlfY(^rIJ4$0+a5{T;@IP#^MuzA!EicRVr4R|J1Xy{ryrC zubf?iAlJ2pO;ci)*ljZAJP)MZ&p1%9hM6$q)I3#jYtUnOVc}HchVfE4l*;bV+qrd? zty6}!6YXd@G76*!QOIlYox|;x36Wcp&gi@D)h^@YQa}frP6kq2xe&J1s*0KaspK+Z z*%InX6s!ODEY2S4@Hw=>WDps-kh#h95|MJdi6xQRcVwTNo-0Upw4)b-d*1!?PwnC| zJhNL|^fP&@A;MhzhMK58J>AAuOb+|K*Mv%^_x&iH%z{$KN9Etl7_;JVgJXy2L%t|Gua~?-jy~&V zM#Z0Fv}vf&qiTsIj4HiYo3U3$im!?lQekg-}OG%ODhw29h>s{NosK2zZP!2mFR=`gwIH~X{Iq@TP* z8s?u$C>U5AVy`~DLCLv@fkEagRzY_2zIu_bAT+m14k#jC=J{a|WU(m{agV&qg1cMS z#w)svIveEb!bvc`PM7xWXcOgi;@13%WyiRr-YXH3hQ0Xuk7~+7K4&H8(3UAUXImeA z{BJ24^xH?;_QQx(6HA^arMJTPC~_3@ZPiJDr?+^+0Vo=GAG>m*;4BH@FXo4sMPo$9 z=ERy7>eXD%IOp77Q?e(cpMJuQA3GnUe3yN8e6Srt`SKkm)G9;6(paU#C#XW}diXIp zsjbiErt*3SL4El&btQv zGo+uN!V|s=lB?&I%sXeEq+?qhIGT*u4wmrQ;%`@5W4IDLCjB1qqhr`@)C1LHzUW^8hna+pD^Le$`VjQm}7m{mHVqH8IT+``> z*PDwKvGemal`OT#TSw(QF>lS2zz%PR*eV}Kk`~L7!pEhWef|TWf265RcfkEJ=_HYC z(hx+w@YCCGb64lCMk|yGO3&1_4)>Q4gcR)wR&#=Jx*GPN*k#H4FIU2e-9kJz*yUZm zcYK?=^8*M#>dzLNWVMAED1wJfA)^M?1z3#Cali~ZfT}XNM^Eka+tHJDID~mpAIpAK zQ{(qC)xsw19Xc&c$f2{0t}C*wNYSYlt65)wr9iT-rAP$l_|vUEojwDDB~9kx*Tb(dX@1gZa)PLI(jg5$;XQk21WqS zIHeuR(|~Tu{~uSiD$&Mng(ZAye`3Mb-|~c-X*9G>Y?lIU4~V6jH;gHH(Kk(zL+~}S zn--!FZGN;KE-<`GN53_K_ZTp)*Y3E;T(~DYY zJLlYouT1X)s@)Ip){CnL9lRZa$zQ)SyhUD*NMx?On281T-?mMf1-ohF#%}gx?RJ=t z(*4Nua1);katPdWerULPQk1V?U}Gxnydw&D&sbyk^Rj9CA>zc8+;Nl1_0(J|WtV#T z+vf?OSq)AVay0wTe4nobuH(rm-p8u z_q`AEe$TPc4*dX~%Q{y%Gf7XfS=uHPKN0EH`FTWMI}AHIduVgY~rebREoch5R!h15yML*|P8oml;s}Li-0$ zKuXF*3zKvr*X$`)JH3Vg`q$YN6!NLtpnLWO^TBPgQnOA!3i7HXBJi(%j!{LbPRR43 zTl!WZV2KLnjFPZvL;Si!Q}ItOJ2ReW=iB^(6ToN?$Y*Q0=<{}S&MuAE$>u@&tW82$ zE&SGdxo#*Sg4~e!1XGnYB&lVVqg~YWXUi9Xr-h=8;%id+p~8v{quLSW*g0A>*m-6x zKr*V{*Y#O_L*VO?+so?a>Uw1-45mgrq1BVykrhHtX*w5&rg#XT<>23HUj{L1B$=Zo zQtGcCX|;LIX>q!W*%CDZK+-4Ckp#C9a9q#QkKE=|VU&@)a?G|#Qt>+K^eC+}u^2*q z(CgayOiJ}-@tlu7FLL*D3Gt9@b{r35cR+~a*X1|wrvw`Jn*q=T8Ark@2OASf#zV;x zcpmb}H|^;16ux5Ls1b^C8t}jDZ6S6yq!`|7WK)g6c2o{h53a$%Lu4k(je<$7>-Yzq zJI;Uqvr_on5dEfCG|CM)3pJjPC#Y7Vtp0F`!=Mz<*4AU;eQrty-pV^>@nP75VwV=v+OeYvk~Em2TOLu> z5UB+rY{C?zJN`X{6@yo1&(MRIIU9z|wM5s@%wcu5pO!v<-`qhRv}vbrYO9ndKj@ij zH*7G`6++-dac^8hBq6*qL&3XZysfGWn9FF~8liq-zg^ziRc4BDP5SkAf_IS-L$9>p zFOp!K;T!6L&w%1vIfqLEoKZIms=#M=u%8V$I)~qqVK6*Qo>aI_X{crmSeVy9eyO_d9_^0? zz8x|>3pi2tC!}^~{so@i!-$XRTgmg{IH|MahbVMXb)o1CzFrxJ+uBwGME%+4pkfa! z{?)#+9+r~8Apbj4tb^N+g|U0t#n_{&gXA+a%pULg!*ALO%^EN|Tl_G(?0RP8LDI8* z_UsarI)+LAZr`0mwCN6il>Uzy6$?Bj*<2@=J$=1GmNX6o@lz-N2>0 zjs_HBs}`EFnu`79xO^oQ}B3&$jyXvy&FWL6ft=M-U*uO zBnv3E{1)7{X5ms$$aop{vScaqy!&tT>=zCa7ql=U7|%#-24<7%+{N*I?nbkZ=Fc$U zHQp+ks_FEV#nA0q3&Lb$#9t?H&G*>9c!N#B5*nC$auJ1gAP7t06caL@Zx9#;NTPx5oN;2|klqK7_wY!9SDE+(|UNUYNh`^kj-wZ znUShuyOScb5lt}Nj+9jO`IvefhM{z1y8>D_y#cS&XJW8n^jsrb%K(9sZl|54MMOhl84KG{X11@=Al%kRW1DX-A-S zisP3sy2@dmQiiTlLS$FOWEZH4v2<1uLeF|EkT$MzFs zDbe7C`)3X4@@=20TEmch#>w?A4cs#5~y58Ja#iHnlKdBSVG(dYQvE6~BPE@XyOT z;?>Im4hyVIl|i!XuV{{Mw&etZoIelhZvxF2XEDMZc2qf(nRZUXJ{M#VEwz;uD&jGH zKm7B=mGZpaoL60qoMdD%1E=W~Q}H)$YWv~o8*|<#xBB^VH;*I0sqBdS()I`HuOkLB z4h)ei3&pVorg$MAVUB^%fQ!s*H5OJ2=ADSmzATRr~;ZO^mX?;bIq)YRa$z#fOt z@IB+h=EM2n!NbS{HsJ(IN-!_}GIMRxTZmNBS2a0kH1~YIot%`9fFYoa9s+M+DY4|G zEl4J348eyn^LF*=T8tm{M_t9vVwbJQpmf=|czLU>45|hf-#FVD(S7c__)z+{(5dG<+J>9LQX- z^o1$OzCYde{@*e98N%V3^r(%g1=tUjjdg3~g1BN2QBA_VIhj6SZN6ZM5(6hKakf$x zGRD0ee9fP%xex?a=)i&rZji$pOV9jql^LeuZRURfbOAllE_#JfGho!K*JkBHx`A`0 zp}zDgo#br$nJK(B71IO)J3hGX6HMk?u-n#)QXT)o-vOZ6fWVB13I54f6t4BJ2Q6jp z^(w;AuIR26uK5I{L_l#V4N*UgshYrsw84NX4ljT&s(M8KMlG|91>iXQWQ{nhC{fHZ z<08p~5?|}dBDYz-a3@DQPi3${1>!C6h{a;6zLD$6F6S5JH(Oxq?aw=!>~~ybdWldn zbEAiVR$Jjp!@AkZ8~ajAh$+rac4ng99>~?6e#fw*K`}y*Osr3vq9j6ccAO!tQp+{?YY^ z;=92}&;ZHst8smBXfU0vjBti)>a@QC35~iLuImRRNVTgUCJk7ckRRQYy6-rf9%alZ z+Z5gD9HSinrD1q4cY;@yUHLmxCYZK&_)?rsUG_}ym5gIOU3^q4k|3`!O%dIeGKyEt zpIgZlY`H0V{SB{lnda-9VE;;TeCZd$r@E?w%DH1J6`TuVm2yr2omtZp>wl^KBRGx3 zD<7L7qMD^{kLO&1gBo@p_cW$3`)cLjACxi$#C9*4hrnK(hPmT82 zWxxDD_YxMq)slZc7M9PZEybk8GAJJYeYqxUKAF1V5F5mU&&WJH#v>C>6E7$7*+{>T zZ2;RU=_7<72U={fx*L6^x*g>Tv=T^s)I=?rr*r)KPW?=J_eR@F*(+~WAW^CeZ3SZU zgn5;{+B`%dL3sRddJ`%AEOZD)7kShd@k%`Ck<)M>#TMJqj^T$3c}m&^s0!5WMP!~` z%SXqU`?vGF6}*606br2D=N~&FEM6wWP3B_{%lg>NW4Zr2Tzk@VD{I0$M}hto*9)XOQ)9EhmkRN+r+{gv&GsRq-aDHqDP)#*!uAmuJC8%$aDL)nmQbx zwnyon0;Wr_)ySwVvzrHf615q>zS>aga@NIX9n`+bUm56Wx-t( zbr0vs>kU%o5;Y5BCuyi9Tzb_|^Yl6Y)N&m#Pmm93>!1`X=4AeU7P#$=h9D>v)D|?? z3gtOh6V4Sg9jB*iv(J8G@R*K_v7ygSC!4^(+kD-}w`bbuOx5gfkyK#bCG3ig~0n8_okDs=H5VpI@g+It@C=j!Wq0(p^?jCp4zSNX+A_o8a;y0H|N6lvi8 z_6_DN`buE6K~4#;j@_}Rx7lMcmSQCgU3dPO6i zIiiWbqK6H2%YOOhw)?hyoXtOfdoK%i5D-d?fJ}T@WK-1Iq4#2_r(YMH^HA+iQ4p_Q zh2O}OXX{>-7nCy^X*D+c0E(6T>zImf$!+_^$I|CkqE(yd$iR5{8=Jf8#nIRQ`8ks# zZY>!EW!NU=l;|T#mK`YQPcB|!J%JxTOcW4)m+@5faT_5Iv#Xj4ppXf1#r8fPi+1g` zQ+4_yN7xZff%oX0#)uVg8q%iwCR^13AQoG%jhDgd&WKP)$E(l?wpW(MX-dmSV-K)& zIfU)1XQZ{;&TOKFey8>s5`5)USC&6VooauH{L)wocQalCv?b+TL?8n3ikm}eAG0Q4 zZ_+uT6SZxON&eJVHnv8L(1@sP|HcA42acvRL*DB5^5Ws9DYih`8*|+n8m2v3IhtSr zn_jZ7Ekc_Df9OX}%6_9S6KHT=os>V8mp!pLG;DaMZIg>eb^LwsFf&nkBW>$Vdgky= zXn(eR2gBkbtYo;LpJS+f_8Jf>BNM_qhq4gMxBOSTJlB5EwQD)^bhmhEp9=kS0O4~? z#>KpUGD0liv7r6kb?ieo&$ssX$ql8yEENWEP^VWhd9ZYTd2s(q!fhP`f1!IlQY27k zeebj*APk>$K6*fI_mO$TB7w0@~%^qP8EGj3FwYxKG+}wX`+w( zw?m($@D_vJaGt_^N=1EI6!*@qj%emMQ~V zD4_0*F3}`=l8b>>#_rEU_D-KR{e(D-$|EYeO+pZ=e%<7Is^GThd2 z6i2bO#GO>i!nB?qk_G|U|G>t85zHwcgC1_4IE&#ursN}I09=(3Yj3LO0H6R(SGnOi zjA;~3jX39@3IIA@-Yi{Ry<^uHc>_9Mf8|5GKt8nIS1u&5|(vR z^K(8K0WkzgSCK4vU`-^V_xV81eZ1qT=_F_M6Vv2KlQV8U&^xteZh0q!Hgv#_oqxK^ z3d-hMK!Kf6e*UsNL+Ds>zs~*d2HD5;`M)u8$?lg5daPmANmMft$8ngVC#tk1+xW8L z+Xno|Xe-M#9ILG4ej-lUJfEVoR~X!AWpMIrj8WWR>BtHB^lju@`H%f%1V=Z3{XQ^e z8wE-IUkANj6Zr*cyFy>#8lWnkz2)=akL;rI{*xR4e_$r)O&rgKqrPMsi*TK#?sY;4#&CizX-Mf2{lZs1x9!J{Sut&7Xknd5II+vZy^1wO8BfKOX&hX{8#QfGR4FkG%Y=jXUh!b)%QO{8syFJ4p`o- zHo?t*V|}Rr?+)cLe#%cyYD?i8a20KZ?)S3^8=eT<3BZ0<0-O!$RA23~1;VR0jW2?U zpk5s#zGKrZ4&cf?I%nEVUl#`pYrBVM-SZ@nK*G=b{icF%)mnAyaPlhYVM}&*r$3n? zj5%uWEluNT^jA)jTU+**;{i&aRUlsRrt8scASnI$yBY>a77PVEBHlrao@%gCPCFkQ zq=I%N2A^!(-eKsc5_%-=ca#_+66 zDsb%=j)pP2#2y8WPNj&YHpCm+%z15_VTp6k5BDj;m?N|B3HH*hP5CTMP7fv?CopAZ z*}~$_%cQ2@_1UN5Q1$fwWB&KwF>T)4O?FvgI6>zY$2{QQYZrCcKe5Jyiit()F6&LO ztGi&>Gwn6%#@UtnsZaDi&wl(5FMizz5Q6*;=6!Qym_Hvx^BpF)#b@vR){E2|Y!hV# zA@8BP9K`xqJDLoCV;@@~e&A^IB|xO%V@sXu9v6)FJr9+{q`OaDc#LE#*v z>1>*vM3(Z7G0I>E^3a8%k;xB{y;$~e0WLZ6I+L7*r7o;)!^3XYfIj3VF(%j>^%X_nVel$AYZlm!{^dO^eRPe}nZ15TK+zW>gbRbazd`WXrHIjlbS-eT>z08w;NBFa-l51xk+ z3DwYf79O>IWHbdkZa$uq92qWpnGb1h)V(LT1u^PJdZp{6TDHn02yDJh^BGwf@)uH~ zOw@~Sy#7F&LfloTt5RyMBN2-42M#E%f)FFJLdLRCh}(aS05o8h2u+lt^Q3Au_GJ~r zyM0-+e_87F2H6~>iS$23;RzD%m=YHV`dhvIP7MHFqow;rmk!j;nz5LI_XRje-67t% znSQ-+uBC}iowE{og@rW|eb$-|{Q$@ESkYhe$vZLJ`DT}4>>!Dumi+}>aDZk}mN?;b z|0ZZyJUK}C>E~(xw$xy`4Fe^f!Yc5qMODnZDZAqXOm63~{gxM|xnguojHmyk{P~G* z_SK!R6jF+VXpjb)oY)_qjU(&zurdeHR^oHFJ?5=nkaUhph!QEz|PlI|kY#1O~Bx zBAD>E%|t(A1o&sqb#;5&MJs?4CZ6;EP>|O=?Y=&ZyQhEhkWU_BC;TtSLw@<|*FUq* z9cFcTmGl>b9S3m7vB;}ZpIl!%pv)@IKL_40gbsdZwQ~;G)dF_;U+rSDk&}q)olcVm zOMDzbE_FtxhBS3)+tvWkqwMiHOHV$po`-4K12%$3_~&VY3X(p5kLJ)oeZ^Q@w?d$w zo+E%US&Y~B?_WunP-WF3c1r5>kigMWeEeogp%JWpWguuVk)_?ErNqQ5N?+=VfJc6P z0RhxY#(!W%gd+8ganh*KB*hGtgr=GQ__?Jjplv$Qz`TF_nm;Mc~%Ftj60P*pW}H0hrw z6v4}XDf3+g@4o^U ze8N`D^*v(hbkbnC*?$--pns+@7;tsh)&(MI9}bzif#Z9HkxWU|7R~W~!&F*DlyQ2e z5!~7<>)l`TLBkv|pjV7=U&Nj?HEAwiG4Uc{gUel$&(M|msmRunO&5iF_xaoKRlIM< zz*DB_%;Ht%2$1m}HJ8|GL!iYQof=KcOUvQs_N>Bzy>$7?Pcp{tY`lJ9o;NQ=3QjsV zzXwU-(wWlHI09Vn?~+)vV@(AH`{9(?PKugqE(e5~7-TsD^Jg0XS{H6Wpl(ZRWs+Ysk zMPtQp(tcl0a$(PRO(3Pc*xcn`mM~R_%e|CY`?}zTlWG+uJZ~oy`fh7!4&@2_WUtP;R#~?Pk7V3jj7F5{Pe{wa%jL zqi^=2`O9~2eGg(lH}W^@{>+=vjN&?rO7=S6bw2A;lQI)CG{G^mw$&N#G%nZVzgp1C zX42Box&gnL+rQ9omtSx>2h8jC%i>ajir!pS_RPuc*G_75ppszGt+be#hcj>Xi01vC zVIYlN=b|~;xq7~ zKWkU?xG4Kf){Dqg57YKFq0Of~YWQjQstCCVgmr_!Y5zQ;1(V0{lZSlrkWU`sME!w> zERHU7%zn^6anzrzoiNRacqYLiK$zf>nPLCU?KR9=6`Ltn+#XR`T6feCogt8M!;uLA zr&Rt3S>{hf?21riw%W=;FEIM@-kHT8Z}| zvX#~ulj0X3!27D13oW9ym<6*`{&#P3Ze^WXJtCBd|1c;iAWGy}d7!OwTGs(Q!JozV z>w>ATFr6IbSA3l=<1Fp@OvnMJQa@zMje+JPx6jEM!@4G&2fjH(mGYuoaxs>&z(aAa zan&`g5)i7K($`F_5!>$o2L6j5I{FldY-ZB1X5K9dFhXzi)yK`DdLh_8Gp@93TkC(0 zA?i!ML~r_^k6_>{Y5tHOmQ|_^6Z3JVoN5X_(j-kzKiwN&MxfcFCXGmGAUqlP1HASB z0KBY$GR40NuyVx(yM=vsuKF%PR3xJI?`=o=;(xtG=KM*?pf)>eW&1L5F$24)?mwEN_9tbfCeD@L!%LLpPg@z2@znT6gYKoFc2;7 zMOBukQDy7&%n`G+b5ecbH1P=nI`hG4Zsqzk-Q%lfp7RxX8uPe`Fn5`IPk{b_ zL!f14LN}gSg5rQ^Yg?bnms!cZYEcK8KJ;~GAC9KUbE9ha+>EG_e$vtvjPNF};4`pj z|CC4ZN?RP2$p3glP;3s}xo8Dh2R@wL4cai`1Ho^-v#v8g`B>Um-t|mCSeiA~y9fC} zJ2QKq7p+@5o@ir0ctD(cN&;Idm;%hw$X&P#WS%dH{Nv4CApc}TvKJCW(Odq#*N@*2 z(uqIl_y$cZ`Sqfawy(S=-_S+dXg;Nex+>Rp!i=sw;g2g3#L=a(0N6)_c1o`~wJt#~KY7R}4~bYfPM~F+K&1%^+w$rj*FZJ7Uhz8Vm!tW`lBnS_RD1`hgOKT4Mpfi1noq=sNl zq3Xn37sE>lM9=b&ZM-M8y!bxe8A(!k(50!yKrqkcn#_-x>X=rQKPusC*QFIL5M(L~ zk-WbBvpVaTkEtWR3ul)Cl@l<9kvwNDvBLBu*74tDyX}jKN4i7O^-!p#lxI&-_xPQC0M6i(8+*X>Co|}*4ztD68wllWf5Ic@b>ik^Z@E`+Ah z`X^LzPskUnK&Yj)r#r{(v)lLyJlD+Z6^v2R?lgP(0#;q^Lesgpel(tC4xPYBUvnmq?7TnC@SX|#XfDBfYn^7|MvViUf2@@f@g1eor7{wsC--;faw(t-FD{4d@(II@0F-KUV9x^=S zH-GL_D3N_=WSC73<9j|HmIonlkRg{hj3EN};gCNf0%t@iO+ZBJo5!NyfDKIJ9r1ob zn4XGg%hcd0$ElBqYc;@M4 zBzt5UquEp>97szVU;M5XlU>YW61~PbF_(4oC!l4`{8ev@;54!B$20&6#&TstVMIN@a94|q#dutGFw+gY_-2{d}--rK#vM0cLW8DIF z&CAT8{snj!#ty^-t{40D+iz(@XqGPmAC{!J*4F$P2`1@34DZQ2Wsq!M&cKU9W6l}@ zF^BdlJzMpQACBhGp2;V4X$9plSpszBY3z>E7b!ycrETA=EiiL5*0uFHLtWK-e#$x0 z^BUkwYCvPioY}i;us6VL2F!MSBPX4dVr1tSc z&n4L9m|x(=oLL|u!RKgR20l0^0gOvgqF&jvdUAOn3qE?x=gmA-6L<||?GB4s@@XRa z%hA`n6Ve)2GptMgOT+$AKgO&~^DX_)&RWs?&i8BT%CvS*CE6ZMS-aI<1n$%5&e=!egu9s8Lhb8Il5JjCRE z@{ms+;#~gN7S;O6T8Tre1hE7!Ao7S*1mG)k#3b;oLzFO^q(oYzafn8|a@sGk zXbfqSR#BO%pvL&yATmkhd*;nQG^|(T*f}kYab-4A(cFFd6$qp~c~#cviDWz63*pMg zBojwo*A+@1^P@2@#l4$qgVLu;cg5Jlo>eQTtq{@@$mX_Iel)Cj{u_`doHNI8boa(s z|G)O`Y`2l?io&p195fk703&(e1jxJkA_-u-yCreT|Lqc!_%aOxxnbGrZc=2`8TVdi z?WxbC7%2T!zy@lQj{1r=K-&L5|FdQ9Qx zSy$WmC#8T=uuqk(k|Y@L1-y1e;U$%0Ir~91mYeIq0a_O*DmZ}>z@T)x2VahvVga(8 z*Lur)1sMP{v4@jl0^^tukU8e?O-bQ_u9<~_@JWc+y(w0fz*B61M60LL#K_;~*~{yn z)`IZNu>w52-N-BhBbu`U=`R7G+;Fa4)Fy90@eWwSiRIA zeslq_N#xw;RopPff<3M|&mWvN8iw)R3geB-LX0jJ7PBb$;^5#D>#OSPg}>Mj^}T&F zk?96y@L+@3Iyo2ht4fFq0Nl2|TPj`szQobY!}6@Pi49mxFQwiX4A5zqJ84kb_1cnppZtgIO@4{o0p44OK)3|bW3CUpIF|5%9ER}u$6i|{5*7zyhOds2ChYn=ZA>%zGlI7vCajQ!h!l|$`huuJ)!x>NsjAQ=v zsKcX@g~tHFzI)+YYen76WS{)Hb^zK0_PEz=pn`Yu+v-?8itc$Zb6c3^Mw z4xMqE6gmByPqCw*5{u;^YJ7lg?3;Dj{4nMApDp~Q3Olc_9U5!uw!_WI!L6K)4Vyc3 z7-(HgP>Nu$ugRXf4!P@)yAJt{4w;?xzyCoB|1KB3u$K60zYp-rf1@{fuP_JZjWOce zJEL63|0(~H1Qf;&C4UZpZJ!bzn3se&a4>XBujE|%5||>GP}a*-Z%7&uKu+(0%E^r0 zM@45o2O6+hu47DWyI|#^-(C zS(%UR!;cB?eCawKGqbGzZTU%Y@NR6FjxkBuk7hh6F_@}{XU?h@HCZ9`Iq9eJ003sm z6-Y7h^s=-go6I=R`TM!}Fdb;Qu0_r)Cgp(Enwu=(+_6 zH%>~N#s|nuv&dNgoNpfxxdX6bxHS*;V;D1v zEx)5nESJdODG1+hw2b!H^aH=#ct-&M7%9LPdpW*&Jx>n9<+)m+{r*&*#>dvmx3nA| zD^@&t1(yOUnAn+^t?xA3xPu*-Fgv_p6K$sb53R%TDKb?!&YqLPn*9;0hY1_gYM&MH z*avD$@NAU2PXW7)WT%J&wziupBS(p1!G_^6S+0P&agm~B+zT4Fh?QYwtQ^dDqur*f)xIXC3lztbc`!sGXV$_DLf|Pz8O1)Q5ySVK6j#cyKB#E z|3)7HAm>wup!WTtc|W`s7{h$nZ!Up8z{;L-Po~EGBm=K)G3b{T6wu=tq5etRBXj1d zz3^z2vv-S$j##ARb~xT#Iw8q0lhK^ho- zayRhx7Faqg1#`5At}iSQZHtCS`liF%-y5&j%-z4l^1P&FXvEuo`8;IO8wJc?b_8A&vmePxRwE+vE}{=(7wcqJ2X!2Nzd<~D2m>~U*!68 zAZ@QrMUdWoU}o>S>yWz+x$BVj0Snr9UaN%s&M*JwYZPWc=ae8;T83+olpbSNOxRxe zbOmapGk8@Wv}+mPvN)BLb7F23pPXGwN`baG<#@g%96!DUhB8emRW;f1$p+59U9#8n zf5YglCeTc}96=Jhlp=@cMUE&{Am)k*X~44db#=BK0GL2aKp#`wOZl+?z~is^I3=ie zDSBq#b1azJqZcL>adMr;F*3gQR2w)okE^jrShwSNlwzVxw^RSLHxstZPyDq2B?aW= z#8cMGwJCw<@Cs~4Jw>!F;|agKrAW}ZdY0P@_z*$788cwFt{tLNjlmk>mofyJV;r24 zT>~oW<1S&lFu4w(m{AyT&A$gAW!iB83{+Pdv-xCxYkYv31oxy)=~w6GQ-rYZ@~_)B z*Vs-eMEZC)0VpXjDmdUb_wEUN?0T1j|7OfFDUg)x7SQP#ioMHChtUD3ynk5&jScQK zWyRO-@^i0ay*0VS&|a^a<(%E8FWFu{-v3z}+8gypV9Hcb8P=$0*KStb zO?x=5wE+q6SrFX=Lkio43}U(RHOm+5@v#F)>sRp21f~QMmRuc-?|ihsjjg1@yTDts z+8B4g*3UKuii?25kahwe%l6Ox8`nq1ltjEa%nhCruooY-Ds~G_xh~9u(n+=nmvcR!kYiiyUD45rm+aX4?XP5 ztgpai`+xj!cLj&^9XU2t@z}F(TQkY959Qy6iDU{+J`{xY-T^a`tv*c;YR@V!Pe6W* zt4cUia!=q)azssKeU>$VRfIpS02)ChDqdh*M>e)L(X*FxE)Txb{(1%ak`t2kSoiN$ zzfcBoDX3+ipW%D^=;f(3*gidlG!L0%ea@v$uv)@Qx05!f{qj*swh3-(ULKZQJo?;K z{+PaUz_vEq*MRPc?`n+hTjqEEfzimx-Nv*&-gU@bhun2YvgT8V*lXW&{cZsjYRmrh zFMq2IgoHqXDm^3$D9^PvqK%!PUDf6Y6gwXq;xsCHO%&e<$X-tZ)^S>=Y(FJ&qI13f z@!{8B5=gN^f()39-}EFvdA~EW{js$<%&`q+=oZaBnVd^ zs4W9VF=B+VC`Zo3pFon*ngD{H>Hd^XPCp5{b#tCGHz*(Fu2%{e%aEW(qVVAYh6H#J z&@QLd-BhSBE^nQx0e}>6{c^IF^MMe5gA6&eWjP# zV=wDRiiKIT&eW$sPhiQ}dXqxRaF_zZcEtoF;J1M~4%-w4(82uY?@g&kE~451%>art zG%K9`Y|04#bK9pTt~useeq_fWhqoC_STJq`UZZ_3y^y3Lw-L zl^+DdFrTS7;*fC4c0JV~Cap%G1~8r*8nvFQZ2_%yT?9H>uV4Q0bEK*KYmI9_Rmuwx zdU9`he4oC=fbtvSJ1PKV$}|;ye9P4aAV{nYbZ^E~S|9$h-1Zug&3i{`#LbnpPOwc9np6ulP?>mb+I8uP|t z4XE-7>$<&_yTDYI2s~>CQ}?(6%;BWgB_kXhHU(T{eEo!8?%z7^lznMW+b;so8lLuA z0V1u@2}E;92>4F4b^v<;a7WIX@zzk!e{Zc|*6Z-Y^Cb0N=ZG1bBz0W_$7JZu{~4oa zj$CtCpS59M^|^Gwq>`#XW%_H6H~+~Tv0rm|zw3~@4!P@)_DXv(q4m>GKmUL8+$C-k z775-MJT+lArFKY-wZXAOlxYlHQJKsP@-OWGxtIk?mP7IyX_eYZiLE9IjD)+|@G(#c zCM=I=&T}W*=S-$jj7;<-rITWRB)wB2spo`7ii^KX*R{{PlM-B~@h3`91z6;8Q|@U^ zXW+95>``3xBd`GE-Rg7p!H0LLLQ>+2UVJ=f>WG<9?{-aD(s!9KnJI=<>3Kc0xX4c9 z*p7S$Dd=elP_U-2V3M2&$JY+UGC#WUiWd_6cDADlv`kId&R#Jpr z_v!S%DSzIWE-4js)uk4 zTw|ZU>Tm1pToKim)($33aFS%SCx?&9_U+qORIvBz&xaqyhOAYt_xlR z0Wl_`VCDF0anw_OmKZ+p-q>NM8oU@C>K9;Jz64AfE6;-|L?0e=d_i=M^Z!+B%#hcQB^_;4u`$)7 z!#SotfF;TAFjPHzs+nj@V@kffHQ&3yvcv4io!Y-G#nG6A`%F*kIe{fIvc335PS_XL zNe4QC92elSega#k#%nA9?H^lbWdJd?|MBts+WZKVI)5I5eEU%UEfZ_1iH?0#a*SD* zi8(h3PQ3z$y6>@d{ZT1I2Z*OqzKr~e(K~fO1X!(k`;2AeQQuo54Q+jCD9ChkpO4|C zN;KO!n8zyC!c#!^Fl(z1j?8P0GWEVSuWQ2N{54xcr`iSVPd>@~S&jc)hun3@U5ETu ehqQ~n>-rZWyHj0vy_v260000 - - - - - Finale for Mac - 2016-09-12 - - - - - - - - - - 7.2319 - 40 - - - 1545 - 1194 - - 70 - 70 - 88 - 88 - - - - - 0 - 0 - - 121 - 70 - - - 0.7487 - 5 - 0.7487 - 0.7487 - 5 - 0.7487 - 0.7487 - 0.7487 - 0.7487 - 0.7487 - 60 - 60 - 120 - 8 - - - - - - Score - - - - MusicXML Part - - SmartMusic SoftSynth 1 - - - 1 - 15489 - 1 - 80 - 0 - - - - - - - - - - 70 - 0 - - 211 - - system - - - 2 - - 0 - major - - - - G - 2 - - - - - - F - 5 - - 2 - 1 - quarter - down - - - - B - 4 - - 2 - 2 - quarter - down - - - 2 - - - - F - 4 - - 2 - 3 - quarter - up - - - - C - 5 - - 2 - 4 - quarter - down - - - light-heavy - - - - - diff --git a/docs/DevNotes/GmMapToMusicXML.xml b/docs/DevNotes/GmMapToMusicXML.xml deleted file mode 100644 index 307a92d83..000000000 --- a/docs/DevNotes/GmMapToMusicXML.xml +++ /dev/null @@ -1,1761 +0,0 @@ - - - - - 1 - Acoustic Grand Piano - keyboard.piano - true - - keyboard.piano.prepared - keyboard.piano.upright - keyboard.piano.grand - keyboard.fortepiano - keyboard.bandoneon - keyboard.piano.toy - keyboard.virginal - - - - 2 - Bright Acoustic Piano - keyboard.piano - false - - - - 3 - Electric Grand Piano - keyboard.piano.electric - true - - - - 4 - Honky-tonk Piano - keyboard.piano.honky-tonk - true - - - - 5 - Electric Piano 1 - keyboard.piano.electric - true - - - - 6 - Electric Piano 2 - keyboard.piano.electric - false - - - - 7 - Harpsichord - keyboard.harpsichord - true - - keyboard.harmonium - - - - 8 - Clavi - keyboard.clavichord - true - - wood.claves - keyboard.clavichord.synth - - - - 9 - Celesta - keyboard.celesta - true - - keyboard.concertina - metal.washboard - - - - 10 - Glockenspiel - pitched-percussion.glockenspiel - true - - pitched-percussion.glockenspiel.alto - pitched-percussion.glockenspiel.soprano - pitched-percussion.gender - - - - 11 - Music Box - pitched-percussion.music-box - true - - voice.percussion.beatbox - voice.percussion - - - - 12 - Vibraphone - pitched-percussion.vibraphone - true - - pitched-percussion.dan-tam-thap-luc - pitched-percussion.ranat.thum-lek - pitched-percussion.ranat.ek-lek - rattle.vibraslap - rattle.ratchet - - - - 13 - Marimba - pitched-percussion.marimba - true - - pitched-percussion.xylorimba - pitched-percussion.gyil - pitched-percussion.sanza - pitched-percussion.mbira - pitched-percussion.gangsa - pitched-percussion.pemade - pitched-percussion.luntang - pitched-percussion.penyacah - pitched-percussion.ranat.ek - pitched-percussion.fangxiang - pitched-percussion.ranat.thum - pitched-percussion.mbira.array - pitched-percussion.marimba.bass - pitched-percussion.saron-demong - pitched-percussion.saron-barung - pitched-percussion.hammer-dulcimer - pitched-percussion.glass-harmonica - pitched-percussion.yangqin - pitched-percussion.slentem - pitched-percussion.giying - - - - 14 - Xylophone - pitched-percussion.xylophone - true - - pitched-percussion.metallophone - pitched-percussion.pelog-panerus - pitched-percussion.xylophone.alto - pitched-percussion.xylophone.bass - pitched-percussion.metallophone.bass - pitched-percussion.metallophone.alto - pitched-percussion.xylophone.soprano - pitched-percussion.metallophone.soprano - pitched-percussion.reyong - pitched-percussion.bonang - pitched-percussion.bianzhong - pitched-percussion.saron-panerus - pitched-percussion.slendro-panerus - - - - 15 - Tubular Bells - pitched-percussion.tubular-bells - true - - pitched-percussion.handbells - pitched-percussion.bells - pitched-percussion.tubes - pitched-percussion.bell-lyre - - - - 16 - Dulcimer - pluck.dulcimer - true - - pluck.cittern - pluck.ukulele - pluck.psaltery - pluck.duxianqin - pluck.diddley-bow - - - - 17 - Drawbar Organ - keyboard.organ.drawbar - true - - - - 18 - Percussive Organ - keyboard.organ.percussive - true - - - - 19 - Rock Organ - keyboard.organ.rotary - true - - keyboard.ondes-martenot - - - - 20 - Church Organ - keyboard.organ.pipe - true - - keyboard.organ - - - - 21 - Reed Organ - keyboard.organ.reed - true - - - - 22 - Accordion - keyboard.accordion - true - - - - 23 - Harmonica - wind.reed.harmonica - true - - wind.reed.melodica - wind.reed.harmonica.bass - wind.reed.diplica - wind.reed.hirtenschalmei - wind.reed.hichiriki - - - - 24 - Tango Accordion - keyboard.accordion - false - - - - 25 - Acoustic Guitar (nylon) - pluck.guitar.acoustic - true - - - - 26 - Acoustic Guitar (steel) - pluck.guitar.steel-string - true - - pluck.guitar.nylon-string - pluck.guitar.pedal-steel - - - - 27 - Electric Guitar (jazz) - pluck.guitar.electric - true - - - - 28 - Electric Guitar (clean) - pluck.guitar.electric - true - - - - 29 - Electric Guitar (muted) - pluck.guitar.electric - true - - - - 30 - Overdriven Guitar - pluck.guitar.electric - false - - - - 31 - Distortion Guitar - pluck.guitar.electric - false - - pluck.guitjo.double-neck - pluck.guitjo - pluck.guitar.requinto - pluck.guitar.resonator - pluck.guitar.portuguese - drum.snare-drum.electric - - - - 32 - Guitar harmonics - pluck.guitar.acoustic - false - - - - 33 - Acoustic Bass - pluck.bass.acoustic - true - - pluck.balalaika.piccolo - - - - 34 - Electric Bass (finger) - pluck.bass.electric - true - - - - 35 - Electric Bass (pick) - pluck.bass.electric - false - - - - 36 - Fretless Bass - pluck.bass.fretless - true - - - - 37 - Slap Bass 1 - effect.bass-string-slap - true - - - - 38 - Slap Bass 2 - effect.bass-string-slap - true - - - - 39 - Synth Bass 1 - pluck.bass.synth - true - - pluck.bass.bolon - pluck.bass - pluck.synth - pluck.bass.whamola - pluck.bass.washtub - pluck.balalaika.bass - pluck.bass.guitarron - pluck.balalaika.contrabass - - - - 40 - Synth Bass 2 - pluck.bass.synth - false - - - - 41 - Violin - strings.violin - true - - strings.yayli-tanbur - strings.stroh-violin - strings.morin-khuur - - - - 42 - Viola - strings.viola - true - - strings.violotta - strings.viol.treble - strings.viol.violone - strings.violono.piccolo - strings.viol.alto - strings.viol.bass - strings.ajaeng - strings.laruan - strings.esraj - strings.arpeggione - strings.igil - strings.erhu - strings.viol - strings.viola-damore - strings.hurdy-gurdy - strings.viol.tenor - - - - 43 - Cello - strings.cello - true - - strings.nyckelharpa - strings.cello.piccolo - strings.kamancha - strings.haegeum - strings.sarangi - strings.erxian - strings.rebec - strings.crwth - strings.dihu - strings.vielle - strings.lyra.cretan - - - - 44 - Contrabass - strings.contrabass - true - - strings.octobass - strings.baryton - strings.rebab - strings.lyra.byzantine - brass.bugle.contrabass - rattle.cabasa - rattle.cog - - - - 45 - Tremolo Strings - strings.group - false - - - - 46 - Pizzicato Strings - strings.group - false - - drum.group.indian - strings.zhonghu - strings.dan-gao - strings.gadulka - strings.yazheng - strings.lirone - strings.kokyu - strings.gaohu - wind.group - strings.gehu - strings.tromba-marina - - - - 47 - Orchestral Harp - pluck.harp - true - - pluck.laud - pluck.lute - pluck.lyre - pluck.domra - pluck.valiha - pluck.timple - pluck.vihuela - pluck.autoharp - pluck.archlute - pluck.marovany - pluck.huapanguera - pluck.harp-guitar - pluck.celtic-harp - - - - 48 - Timpani - drum.timpani - true - - drum.kendhang.ciblon - drum.bodhran - drum.kpanlogo - drum.log-drum.native - drum.log-drum.african - drum.log-drum.nigerian - drum.repinique - drum.kanjira - drum.hand-drum - drum.pandero - drum.mridangam - drum.kenkeni - drum.jang-gu - drum.pakhawaj - drum.kendhang - drum.pandeiro - drum.atsimevu - drum.frame-drum.arabian - drum.kagan - drum.tinaja - drum.timbale - drum.kendhang.ageng - drum.sampho - drum.pahu-hula - drum.sangban - drum.dabakan - - - - 49 - String Ensemble 1 - strings.group - true - - - - 50 - String Ensemble 2 - strings.group - false - - - - 51 - SynthStrings 1 - strings.group.synth - true - - - - 52 - SynthStrings 2 - strings.group.synth - false - - - - 53 - Choir Aahs - voice.aa - true - - voice.vocals - voice.female - voice.child - rattle.afoxe - voice.baritone - voice.alto - voice.aw - - - - 54 - Voice Oohs - voice.oo - true - - voice.doo - voice.kazoo - voice.male - voice.bass - voice.ee - voice.mm - - - - 55 - Synth Voice - voice.synth - true - - - - 56 - Orchestra Hit - synth.group.orchestra - true - - drum.group.chinese - - - - 57 - Trumpet - brass.trumpet - true - - - - 58 - Trombone - brass.trombone - true - - brass.mellophone - brass.bugle.mellophone-bugle - brass.trombone.contrabass - brass.trombone.tenor - brass.trombone.alto - brass.trombone.bass - brass.helicon - brass.bugle.baritone - rattle.jawbone - brass.sousaphone - - - - 59 - Tuba - brass.tuba - true - - brass.sackbutt - brass.didgeridoo - brass.sackbutt.alto - brass.sackbutt.bass - brass.sackbutt.tenor - brass.tuba.subcontrabass - brass.wagner-tuba - brass.tuba.bass - brass.bugle.alto - brass.rag-dung - brass.shofar - brass.bugle - brass.ophicleide - brass.bugle.soprano - brass.cimbasso - brass.vuvuzela - - - - 60 - Muted Trumpet - brass.trumpet - false - - brass.trumpet.pocket - brass.trumpet.piccolo - brass.trumpet.slide - brass.trumpet.baroque - brass.trumpet.bass - brass.trumpet.bflat - brass.cornet - brass.trumpet.tenor - brass.trumpet.c - brass.trumpet.d - - - - 61 - French Horn - brass.french-horn - true - - brass.kuhlohorn - brass.vienna-horn - brass.conch-shell - brass.cornettino - brass.alto-horn - brass.cornett.tenor - brass.alphorn - brass.cornet.soprano - brass.posthorn - brass.fiscorn - brass.saxhorn - brass.baritone-horn - brass.natural-horn - brass.cornett - brass.horagai - brass.flugelhorn - - - - 62 - Brass Section - brass.group - true - - drum.group.ewe - brass.euphonium - brass.bugle.euphonium-bugle - drum.group - rattle.ganza - - - - 63 - SynthBrass 1 - brass.group.synth - true - - brass.serpent - drum.group.set - - - - 64 - SynthBrass 2 - brass.group.synth - false - - - - 65 - Soprano Sax - wind.reed.saxophone.soprano - true - - wind.reed.crumhorn.soprano - wind.reed.saxophone.sopranino - wind.reed.saxophone.mezzo-soprano - wind.reed.saxophone.subcontrabass - wind.reed.saxophone.sopranissimo - - - - 66 - Alto Sax - wind.reed.saxophone.alto - true - - wind.reed.saxophone.melody - wind.reed.heckelphone.piccolo - wind.reed.saxophone.aulochrome - wind.reed.heckelphone - wind.reed.sarrusaphone - wind.reed.crumhorn.alto - wind.reed.saxophone.tenor - wind.reed.rothphone - wind.reed.saxonette - wind.reed.saxophone - - - - 67 - Tenor Sax - voice.tenor - true - - pluck.ukulele.tenor - rattle.televi - voice.mezzo-soprano - voice.countertenor - voice.talk-box - - - - 68 - Baritone Sax - wind.reed.saxophone.baritone - true - - wind.reed.saxophone.bass - wind.reed.saxophone.contrabass - - - - 69 - Oboe - wind.reed.oboe - true - - wind.reed.octavin - wind.reed.rackett - wind.reed.oboe.piccolo - wind.reed.bombarde - wind.reed.duduk - wind.reed.oboe-da-caccia - wind.reed.houguan - wind.reed.pibgorn - wind.reed.tarogato - wind.reed.rauschpfeife - wind.reed.albogue - wind.reed.oboe-damore - wind.reed.dulcian - wind.reed.arghul - wind.reed.guanzi - wind.reed.hulusi - wind.reed.chalumeau - wind.reed.mizmar - wind.reed.piri - wind.reed.mijwiz - wind.reed.alboka - wind.reed.diple - wind.reed.hne - wind.reed.pi - wind.reed.oboe.bass - wind.reed.zurla - wind.jug - wind.reed.zhaleika - - - - 70 - English Horn - wind.reed.english-horn - true - - wind.reed.hornpipe - wind.reed.crumhorn - wind.reed.crumhorn.tenor - wind.reed.khaen-mouth-organ - - - - 71 - Bassoon - wind.reed.bassoon - true - - wind.reed.xaphoon - wind.reed.contrabassoon - wind.reed.crumhorn.bass - wind.reed.crumhorn.great-bass - wind.reed.taepyeongso - wind.reed.tubax - wind.reed.basset-horn - wind.reed.bifora - wind.reed.bawu - wind.reed.contrabass - wind.reed.jogi-baja - - - - 72 - Clarinet - wind.reed.clarinet - true - - wind.reed.heckel-clarina - wind.reed.heckelphone-clarinet - wind.reed.clarinet.piccolo.aflat - wind.reed.clarinet.alto - wind.reed.clarinet.bass - wind.reed.cromorne - wind.reed.clarinet.eflat - wind.reed.clarinet.bflat - wind.reed.clarinet.basset - wind.reed.clarinette-damour - wind.reed.clarinet.contrabass - wind.reed.clarinet.contra-alto - wind.reed.clarinet.a - wind.reed.launeddas - wind.reed.trompeta-china - - - - 73 - Piccolo - wind.flutes.flute.piccolo - true - - - - 74 - Flute - wind.flutes.flute - true - - wind.flutes.flute.double-contrabass - wind.flutes.kawala - wind.flutes.di-zi - wind.flutes.ney - wind.flutes.xun - wind.flutes.flute.bass - wind.flutes.khlui - wind.flutes.koudi - wind.flutes.danso - wind.flutes.flute.contrabass - wind.flutes.flute.alto - wind.flutes.flute.contra-alto - wind.flutes.fujara - wind.flutes.kaval - wind.flutes.flute.subcontrabass - wind.flutes.xiao - wind.flutes.nose - wind.flutes.venu - wind.flutes.fife - wind.flutes.knotweed - wind.flutes.hun - wind.flutes.tumpong - wind.flutes.ryuteki - wind.flutes.flute.irish - wind.flutes.flageolet - wind.flutes.dvojnice - wind.flutes.whistle - - - - 75 - Recorder - wind.flutes.recorder - true - - wind.flutes.recorder.bass - wind.flutes.recorder.alto - wind.flutes.koncovka.alto - wind.flutes.overtone.tenor - wind.flutes.recorder.tenor - wind.flutes.recorder.descant - wind.flutes.recorder.soprano - wind.flutes.recorder.sopranino - wind.flutes.recorder.contrabass - wind.flutes.recorder.great-bass - wind.flutes.gemshorn - wind.flutes.recorder.garklein - - - - 76 - Pan Flute - wind.flutes.panpipes - true - - wood.pan-clappers - wind.flutes.shepherds-pipe - wind.flutes.nohkan - wind.flutes.palendag - wind.pipes.highland - wind.pipes.uilleann - - - - 77 - Blown Bottle - wind.flutes.blown-bottle - true - - wind.flutes.whistle.low-irish - rattle.maraca - rattle.caxixi - rattle.hosho - wind.flutes.whistle.tin.bflat - - - - 78 - Shakuhachi - wind.flutes.shakuhachi - true - - wind.flutes.hocchiku - rattle.shaker.egg - wind.flutes.shinobue - rattle.shaker - wind.flutes.shvi - wind.flutes.whistle.shiva - wind.flutes.whistle.slide - - - - 79 - Whistle - effect.whistle - true - - effect.car.stop - effect.high-q - effect.stamp - effect.starship - rattle.wasembe - effect.whip - effect.whistle.mouth-siren - rattle.sistre - effect.whistle.police - effect.whistle.train - effect.whistle.slide - - - - 80 - Ocarina - wind.flutes.ocarina - true - - wind.flutes.quena - wind.flutes.tarka - wind.flutes.bansuri - wind.flutes.suling - wind.flutes.whistle.tin.d - wind.flutes.whistle.tin - - - - 81 - Lead 1 (square) - synth.tone.square - true - - synth.theremin - synth.tone.sine - rattle.lava-stones - - - - 82 - Lead 2 (sawtooth) - synth.tone.sawtooth - true - - wood.tonetang - - - - 83 - Lead 3 (calliope) - wind.flutes.calliope - true - - wind.flutes.whistle.alto - - - - 84 - Lead 4 (chiff) - pluck.synth.chiff - true - - pluck.synth.stick - - - - 85 - Lead 5 (charang) - pluck.synth.charang - true - - pluck.jarana-jarocha - pluck.jarana-jarocha.segunda - pluck.jarana-jarocha.primera - pluck.jarana-jarocha.tercera - pluck.jarana-jarocha.mosquito - pluck.cithara - pluck.charango - pluck.jarana-huasteca - pluck.guzheng.choazhou - pluck.chitarra-battente - - - - 86 - Lead 6 (voice) - voice.synth - false - - voice.soprano - - - - 87 - Lead 7 (fifths) - synth.group.fifths - true - - synth.group - - - - 88 - Lead 8 (bass + lead) - pluck.bass.synth.lead - true - - - - 89 - Pad 1 (new age) - synth.pad - true - - - - 90 - Pad 2 (warm) - synth.pad.warm - true - - - - 91 - Pad 3 (polysynth) - synth.pad.polysynth - true - - - - 92 - Pad 4 (choir) - synth.pad.choir - true - - - - 93 - Pad 5 (bowed) - synth.pad.bowed - true - - - - 94 - Pad 6 (metallic) - synth.pad.metallic - true - - - - 95 - Pad 7 (halo) - synth.pad.halo - true - - - - 96 - Pad 8 (sweep) - synth.pad.sweep - true - - - - 97 - FX 1 (rain) - effect.rain - true - - effect.crickets - rattle.rain-stick - effect.car.engine - effect.air-horn - effect.car - effect.trash-can - effect.train - effect.frogs - effect.scratch - effect.wind - effect.marching-machine - effect.snap - effect.car.pass - effect.car.crash - rattle.rattle - effect.dog - - - - 98 - FX 2 (soundtrack) - synth.effects.soundtrack - true - - - - 99 - FX 3 (crystal) - synth.effects.crystal - true - - - - 100 - FX 4 (atmosphere) - synth.effects.atmosphere - true - - - - 101 - FX 5 (brightness) - synth.effects.brightness - true - - - - 102 - FX 6 (goblins) - synth.effects.goblins - true - - synth.effects.rain - - - - 103 - FX 7 (echoes) - synth.effects.echoes - true - - synth.effects - - - - 104 - FX 8 (sci-fi) - synth.effects.sci-fi - true - - - - 105 - Sitar - pluck.sitar - true - - pluck.sarod - pluck.se - pluck.saz - pluck.tar - pluck.dutar - pluck.setar - pluck.saung - pluck.ektara - pluck.guitar - pluck.zither - pluck.sanxian - pluck.tambura - pluck.sallaneh - pluck.musical-bow - pluck.tambura.male - pluck.veena.vichitra - pluck.tambura.female - - - - 106 - Banjo - pluck.banjo - true - - pluck.mandocello - pluck.mandolin.octave - pluck.bajo - pluck.ruan - pluck.biwa - pluck.barbat - pluck.begena - pluck.mandola - pluck.bandura - pluck.bandola - pluck.mandora - pluck.mandore - pluck.dan-bau - pluck.baglama - pluck.mandolin - pluck.bordonua - pluck.bouzouki - pluck.langeleik - pluck.balalaika - pluck.bandurria - pluck.mandobass - pluck.dan-ty-ba - pluck.dan-tranh - pluck.banjolele - pluck.dan-nguyet - pluck.banjo.tenor - pluck.balalaika.alto - pluck.vihuela.mexican - pluck.balalaika.prima - pluck.tambura.bulgarian - pluck.balalaika.secunda - - - - 107 - Shamisen - pluck.shamisen - true - - pluck.guzheng - pluck.sanshin - pluck.veena.mohan - pluck.veena.rudra - pluck.bouzouki.irish - - - - 108 - Koto - pluck.koto - true - - pluck.santoor - pluck.oud - pluck.domu - pluck.pipa - pluck.tres - pluck.kora - pluck.veena - pluck.kanun - pluck.tiple - pluck.guqin - pluck.xalam - pluck.ngoni - pluck.komuz - pluck.kobza - pluck.cuatro - pluck.kabosy - pluck.yueqin - pluck.theorbo - pluck.kantele - pluck.kayagum - pluck.geomungo - pluck.kutiyapi - pluck.gottuvadhyam - pluck.zither.overtone - rattle.kpoko-kpoko - - - - 109 - Kalimba - pitched-percussion.kalimba - true - - pitched-percussion.cimbalom - pitched-percussion.kantil - pitched-percussion.balafon - pitched-percussion.angklung - pitched-percussion.tsymbaly - pitched-percussion.gandingan-a-kayo - pitched-percussion.crystal-glasses - pitched-percussion.bianqing - pitched-percussion.likembe - pitched-percussion.khim - pitched-percussion.kulintang-a-tiniok - pitched-percussion.kulintang-a-kayo - rattle.kayamba - pitched-percussion.kulintang - - - - 110 - Bag pipe - wind.pipes.bagpipes - true - - wind.pipes.gaida - wind.pungi - - - - 111 - Fiddle - strings.fiddle - true - - strings.fiddle.hardanger - strings.leiqin - - - - 112 - Shanai - wind.reed.shenai - true - - wind.reed.sheng - wind.reed.maqrunah - wind.reed.tarogato.ancient - wind.reed.suona - wind.reed.algaita - wind.reed.sipsi - wind.reed.zurna - wind.reed.ken-bau - wind.reed.dulzaina - wind.reed.cornamuse - wind.reed.nadaswaram - wind.reed.sopila - wind.reed.surnai - wind.reed.sralai - wind.reed.shawm - wind.reed.rhaita - wind.reed.sorna - rattle.shekere - - - - 113 - Tinkle Bell - metal.bells.tinklebell - true - - metal.flexatone - metal.bells.bell-tree - metal.triangle - metal.bells.trychel - metal.bells.tibetan - metal.bells.sleigh-bells - metal.bells.jingle-bell - metal.bells.cowbell - metal.bells.bell-plate - metal.tamtam - metal.bells.temple - - - - 114 - Agogo - metal.bells.agogo - true - - metal.bells.almglocken - metal.adodo - metal.bells.carillon - metal.bells.ghungroo - metal.gong.gandingan - metal.gong.ageng - metal.gong.agung - metal.bells.hatheli - metal.bells.gankokwe - metal.gong.thai - metal.gong.luo - metal.gong.kkwenggwari - metal.anvil - metal.babendil - metal.bells.wind-chimes - metal.bells.dawuro - metal.gong.kempyang - metal.gong.kempul - metal.bells.sistrum - metal.gong.ketuk - metal.gong.chanchiki - metal.kengong - metal.bells.church - metal.bells.zills - metal.bells.chippli - metal.bells.mark-tree - metal.gong - metal.bells.chimta - metal.bells.chimes - metal.bells.khartal - - - - 115 - Steel Drums - metal.steel-drums - true - - wood.stir-drum - metal.spoons - metal.singing-bowl - metal.gong.singing - metal.musical-saw - metal.hi-hat - metal.jaw-harp - metal.murchang - metal.brake-drums - metal.guira - metal.hang - - - - 116 - Woodblock - wood.jam-block - true - - wood.sand-block - wood.wood-block - wood.agogo-block - wood.temple-block - wood.granite-block - wood.tic-toc-block - wood.ipu - wood.slapstick - wood.gourd - wood.guiro - wood.ahoko - wood.kagul - wood.bones - wood.guban - wood.drum-sticks - wood.kalaau - wood.kubing - wood.kaekeeke - wood.kashiklar - wood.castanets - wood.hyoushigi - wood.agung-a-tamlang - - - - 117 - Taiko Drum - drum.taiko - true - - drum.pueblo - drum.tabla - drum.powwow - drum.log-drum - drum.kick-drum - drum.tabla.dayan - drum.tabla.bayan - drum.buffalo-drum - drum.bata.okonkolo - drum.slit-drum - drum.tambourine - drum.the-box - drum.uchiwa-daiko - drum.tan-tan - drum.tangku - drum.tar - drum.darabuka - drum.zarb - drum.axatse - drum.shime-daiko - drum.chu-daiko - drum.chenda - drum.tsuzumi - drum.o-daiko - drum.tamborita - drum.nagado-daiko - drum.inyahura - drum.ko-daiko - drum.taphon - drum.sabar - drum.daibyosi - drum.ghatam - drum.geduk - drum.teponaxtli - drum.naqara - drum.djembe - drum.sakara - drum.nagara - drum.tenor-drum - drum.bendir - drum.hira-daiko - drum.tumbak - drum.dumbek - drum.bongo - drum.talking - drum.toere - drum.tasha - drum.kudum - drum.dholak - drum.thavil - drum.udaku - drum.madal - drum.surdo - drum.maddale - drum.okawa - drum.okedo-daiko - drum.dafli - drum.conga - drum.tamte - drum.dhol - drum.ishakwe - drum.bougarabou - drum.ashiko - drum.khol - drum.snare-drum - drum.dondo - drum.doun-doun-ba - drum.cajon - drum.kakko - drum.tama - drum.kidi - drum.duff - drum.naal - drum.sogo - drum.frame-drum - drum.daff - drum.doira - drum.ibo - drum.cuica - drum.udu - drum.def - drum.apentemma - drum.bass-drum - drum.atabaque - drum.igihumurizo - drum.bata.iya - drum.lion-drum - drum.lambeg - drum.bata - - - - 118 - Melodic Tom - drum.rototom - true - - drum.damroo - drum.bata.itotele - drum.fontomfrom - drum.atoke - drum.bombo - drum.gome - drum.riq - drum.tombak - - - - 119 - Synth Drum - drum.tom-tom.synth - true - - drum.tom-tom - drum.slit-drum.krin - - - - 120 - Reverse Cymbal - metal.cymbal.reverse - true - - metal.cymbal.tingsha - metal.thundersheet - metal.cymbal.manjeera - metal.cymbal.suspended - metal.cymbal.ching - metal.cymbal.ceng-ceng - metal.cymbal.finger - metal.crotales - metal.berimbau - metal.cymbal.chabara - metal.cymbal.tibetan - metal.cymbal.crash - metal.cymbal.kesi - metal.cymbal.tebyoshi - metal.cymbal.hand - metal.cymbal.ride - metal.cymbal.chinese - metal.cymbal.splash - metal.cymbal.clash - metal.cymbal.bo - metal.cymbal.sizzle - metal.gong.chinese - - - - 121 - Guitar Fret Noise - effect.guitar-fret - true - - effect.guitar-cutting - - - - 122 - Breath Noise - effect.breath - true - - effect.bubble - effect.heartbeat - effect.thunder - effect.burst - effect.pat - effect.bullroarer - - - - 123 - Seashore - effect.seashore - true - - effect.door.slam - effect.door.creak - effect.horse-gallop - effect.stream - effect.siren - effect.scream - - - - 124 - Bird Tweet - effect.bird.tweet - true - - effect.bird.nightingale - rattle.birds - effect.bird - - - - 125 - Telephone Ring - effect.telephone-ring - true - - effect.metronome-bell - - - - 126 - Helicopter - effect.helicopter - true - - effect.metronome-click - effect.flute-key-click - - - - 127 - Applause - effect.applause - true - - effect.explosion - effect.aeolian-harp - effect.jet-plane - effect.hand-clap - effect.laugh - effect.slap - - - - 128 - Gunshot - effect.gunshot - true - - effect.footsteps - effect.punch - effect.laser-gun - effect.lions-roar - effect.machine-gun - - - - diff --git a/docs/DevNotes/IllogicalVoiceTags.png b/docs/DevNotes/IllogicalVoiceTags.png deleted file mode 100644 index d9036a8627bad6b610bb290c5818f7b28ce81556..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 220417 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

f{apl`{#-?7e zO-ITOt~Fl)_`pFvqtZ%HkhQgxDp&Jx$;9iK<2q>kAA!bn%R9;@P;@zb-C;pqI!tkW zi8YRi*Z`1In>RNDzD#GP;16kC?kJe&a$TB`{1{8NY$T0`xdPIPNDT}gIO?Yq*C+m@ z7`q)`v~y9Yfzy~BV{!&~XhOlQfP?v)vWnA#fD@%f88_Y~N8S{u)YxNCO34$zzHhBy zZifABKD>6d&a0;#BYV1I(rXxxMV9sh5F|?dx>oI`vF**wwg7q{ingpLp0j|)D>i0w z-udiSLgAR5#`lTo^iJ^1(RfXrV;imeA1U6gB<_KvKv##EK%lSavwK=6CqWJQ17`<`{4A815w z5wT;w?oeR-0yww%{c;~UkOe`cjYCrHZm-Ooz4$OzLb9Fs-a5M@4?3HyrOoO!17usX zAdp=XFw{M?Bv^hlmU&5>xH;_WgLh6gP;LU{psdmjWBS~q=-SESXH5s}vPe`8E>X}t zynFZM)h7=>0f=K=v48TXy~cuCuWxo=@+oZu7~7LqEOH6$JHVD8zX~)3ayb3X+MXzL zpWF=q2axTlwWQJo^=*CrW*9r;Z%z(mOg^~J@4xPl(j1mn>P60xU8fF-txa-t@nO|| z>!G!E#x8J)gA${@$7f>llde`!Mv)FuDi=K40Z~9lc0EcbtXrF)8 zA+I{*RfpIw-=;%m*L=LcJ`NzvWSg)hWHQxWu@Sq?cj*NQOQ2>R8*`@5RJW8ET7*QW z#h5jUZK*p-Kt2IFPTV;)KLK6^Hl%d!3BmH_6^VP712ScwS$d*B8!w7*o9&Q!Cw8ag zu@3WuFToSoaH4&YPc+;lh5)n1P zn+blM!p8QH@tnyqZ=!*ZSe6TOSka;z{l3w^GvB`=cUQ+R8#W-6R?aDXm|V>7G3JI3 z*?S6no||6Jg#fGZP{gF%k(UjHZH`j*8cLf|Hs(7pSgET!4a>Z|b^pwMGJWe8Fq`=d zs$Qy%ln0OwO6SZJ>Z^9$VknkMGbuAy(YjM^kMfEA@VuhKQ`%>3oSN5|9G_-IqUnFpr2%xmjs<4Qr6K=}rcyjagS6n|0OF-+A<-UY;r!F7{) zwO+?|f$HwvZyU;YYNfpdvb0_*lNi`8DfxgHeSc7%uRwz{hGv4bYL@=oGLR)j{{hc;9P3uIMs&(gSV8HO@{!!}FOJUYO%_gNRt z{yjMa-sB@|e`NliNN+2xn!abjDm(Lg@Yy|Z|NgVL{5_2z5PSo;KF**P=%HUw@dZ<# zOGL-qrP5D{?yVne-|qaddhh40ak_E%Ctz}9gN z6XvDE78zU>mz(`}`O|zD7h_oo!^yM|5M)USP#@pQr#TF0wd23T-YbHOd{Ke!<4adwMBE^$0#imEtqkA1Lh{K>i@#F{ z)DCry!oJ=rtXJ8%QWM}5li_qM3rfsAqlzefxDN>~gS6I;3!^Z#hwO-r(-hL%g~(DuPQtq^UtYK=G6Xpy7Ed()$HKb;T!>t59`6v@Or^<}ByB9XM4< zr=FWr`@QO?r!Fylc<_5TBB>8mDO-&yiX~CVjN^xX*vSRDV!&3@7F&eG_49PW^&Gbgd|q5ra%@|$6q#k!d|We)k;HYlbuoAHQSfukIXWc5 zv?e+{U@`4|5TLYbPOYErm-zhJDbH`pvfJK(`Lxk_WE5bw=YRy#EMCN}MPz-<*fF9pFWQa{y=d_rks_XJ1%E%7l-lM_#X<7p z`;;WV^JOGzonTB36K$i+oA+t1>Y#`MC2MAx;S%Z2vCT?qUVnsI5=NYvrCOyd)2df8 zTB{tHk{Jnb?6;H-*(SEkU24OZb!SvDORshAWR1$x(+0(OU^+ChAnJZR@WmNSz7$2N zHNu@Y6ej}g>lL~wjo&9A`RV#FwRC-`ZB=3SdxJcZfC14dP@(2h2o)L&P~ z^yM8#|6a8aoLV@*%P%P1C7}H&+Za^+;bF}6$2;83lieDA)#RM?UCbzbA>BO&G`A=H zJf;8X_Ms27D6)q*E`_KXxH2vT!x2m&_ss%s8*GGS(!+Mv-t#`3|^-snh3f6o2$L5pG zzIQKDNzT^%_x1kIuvq)v)+)H9XK?}gBKO7ZRqj-XaA+O17Mln^Ast4pPr1LIqFsWO zwb48AU-^-t%s-vTPeO#UY&%v7DsFN>%nMy+!9&{E(VxOy3J)I?pEhyeDrzuI{qBT zYj?{;wS~tE&pGJ0o!}N@l{gIIGfeBnQdaLs;Cd4EO#FgIy@!lxkzR*QsY8rUP~BHP zYjI!>_#&972AOVGL*mlU63ya`?|q}}Kp2K3sri#3186KUM@REhurxx=4T$|T7~G8( zp&a8&F;4EK_%3bZ&`xUOQcgxIaDGtx(+5D%4%fAidYy~aYYOxIJGgn-vCr%1hyJ8a z^p7|9zJE`-rKcP+v`+i=y-SO5FK~6euGhOl-EOto+6WJe0SO3HCibjqkyo_lQgcMg zOar4^tgR|cK3)sC^Z$;GO;K}8w)jA%Yk8#6kvFEvR~U}Q#rw3sA+}msiLF6`yQt&N zr!X9{X2>_C*EKM9D*BgZ?Q`0|$VRmOnv_{PqAjNWIPx=2K9e$24u!c@KIDalU|_~# zZra-UDW+$^t#M8KAk8|Q>NTGI6u6{D(BvTrW@?PoCpmPl+t_H}R z`J+n!oyc`ZcaA&Mm~rtRHyONE{R)awMkSh?sX}bm$vZii=Kodk$+b2y0P6n`H6)1Z zW+=1@o2*s5JqDa;{0YAX{yNrhN3CDM;$^9KgwhxtyNo6pXiS8!biMBzd%E#o@vD9t zKky)ppHlE*1|+z#>d(@qnAS5_8ka;8pSE?GPkJff**Vl3>fxgmvfVzZ0Hv3^u}mjn zod1vt+>Ts+a}X&K=2_+mCA$F}mM>?(tp9Q_3p?8=>mRZ!y(?N6)D{9+nOUCcKjEkn zrmiB8+kE={5==r4@1*zJnDjT9fu2t2h0`b%%Rsl|J2}(Zfvx;x%fnx*dSotGljFris(yjZniUgo#d`AO_#uOcqq)7c+N}Q`h#I0VV|Ku4%oU zOqTvsqIQF0OP`cWb7<5291+kWXjoG7vL!=9tJK>qi%8ITuH^}9zGLtRexB$yZ)M;@ zDpUSzfHHb%P@l3=#Wmz}{Qnyf34mujb(2JmlTvl%2{Q~rtPNs27cN z8k&E;AQ4LQ1jW`Vl^-1YrH%TenKQ;902;~*_iT)EMQD-kMFp-b+oSa1KOlKaC_$JB zcMN%64$ho8opG8dmTN4H+NRBLS&bj8l^@gSeff4cG}?w37Fk~1$JDW2^%c;*UZI6V zG8M`zWc&@tJI$QF%F<*X_Nh!%-;gs@g?3q)lgD#FBRD^CyGbRC6C?Be%j^GW;_>xN>zvR*U^BQ0$M zm&2<5T-mI#<8Bj}r>pI3n69gM3D_!orSJvKN>Mx#nU__DXW&rz5xMN_Mi6mkY=dkC zpPSEKh|NNtTQo;0>I>06bo z9ns6x-P5sSyTT{)u$~8H?##d3rRxix1+bL7L}OdWc=&uO?v`%!QCH+%D`aJHYISa^ zw7Q6tJNfzGm30?~j4~-B*D167x0Q8j(9AfkYia@FL)jl&F0}8Cyx8yzY{vNV zwA8P}g=;q%I8CR8qTlxFydr$Jr{}v3uQv?yl<=?rUmH5&9V2ngQ-{m@Fu;lQJCLH|pHugYBr*C_;4^lOpr5Au! zne|IZM5IVP-Z-fdIjya5<$aXc4_tWdQ5L`N3cf4ND`gPmlJ)D8zpF`q3jY#D!r`TM z?!p@5rO=FCFr1#9c4^wnb)!1XYG3T{1@%NCnc)qU$_<*nJP0a#_iSbIg#CR?*pD}P zp#tPo*7pWCQ6@CA?;Waf&<9DqSU08u{4Jv1EQ4>R5@Gi`m$LinEjpavB##nh$16IB z^c-|f#si7AhUBd3H6L;;N$0iQd zioz#8$sFKJAy2p>4%79Z?eKICX=pSf74>v;i*@B|mg>@O2kfxJsZ%mI&Ksv9*qs}5 zb>gnc5lpN(o*BR4xd!w-36SrOh*NF0n|vuvkQ)fX0LQ_^3EWh~ z+(C~o2GpC4Gpz$*V#*?$FEQ&u0}@1j3a;)@q^VU#x=YUAZRCRVtSG zkLjPAJ4)4$5aZ|gBV9~Aw37(pO-*n62W*xGt)`li?iVp~5>G6$D7(-4{&P{A^wu zdN4!L&)He*j^KIIAO@DhunSV1OI$XKovFE|&M#8(US6U7r&hFaVVLah5cxD0Ruvnr zzuP$p4iZdT&MFau)9DhPstQprV*1f8Q1~b@;^zZHf~SlD zGYo+w8YVM;v(ye6#|8eSlIE-Jk7YP}twX%o3`f0l7Kk6Yar*7a+WP$suxciwgLU$L zwY-dm09fUg4e|cqQk`yv{)`5aj$MB_)58&xe|kNdgnK%pf3jj;H|~FsHp~QHlL)z~ z)#l8>$dR;~?wpQ`!Kb+N5z|{D7RdMTCm9Q&Wba?QUg%Z*QL-&|{Tm_qx=4s!o|B}M zYH`u%O-h7fE#h)CuZyocUH4q}Lt<>pIy<^l(9r>&`j7j?cf)(4>bn3#yb%o}8EjToGhb)?lC8N8zi&`l6kish$ z=8YqYc`nc8Sy7{4!Ck!|Uj?z5TQn50b%HsZIT|D;+9S$m6seOp5l`6fZjc1|21f8`J6tYG};0=n^#WSE)dj6(~ zejr`T%wOcve53qB8=3E2l=}YPV4L=Rh6l1sh&C!3K@uaVaPNKGB_^r{SB4(5^X|RxEi{M{>#~v1gDA4N8 zhl=xQahk{m$XbrKvX$;AoH*na5-1NBMe!@S;Emne^z^q`u|nq*+Q^&(gv`oVtM_NIh>^;9`ccJ%k=Iz zr<@7YHrS-&6BQ|#9n;RwNt&=-Pj^o`@haofzrm~YH;Z(MrbjbE$W9_H=tJ(06dM-{u(oIr|3LUzOp~^k{CV%dKXceVB@ghX%3ayuLHsI3Qo!bt>i} zeE3y_lF&c(v*B-HOj|xTz_PU(DmsP7M$h9WU{>>SPic9EA$J$A6KaTEJ^p7 ze9|AR1XN?39ds$zBa+@bU@$4sbTc3I5SXlL_HKJ(PJDlKaC)VzqHi zf#+X$MH=p4K*cK$r7|DrsqdZXvDkhP5yWq&fV%~=aoGVo%(9V9ilzrVare1H`zuL4 zB1DhR78fR22j`KZ3$u-W_R83r2@p))VDBy#nt9!^4mgU1#`2@X-4>+~>E>BVFpA>> zC$Fjy>YX4E4x|b=(onmV`=?$PDI}vra;Nr>^vQ&Q=i!%(jv)N?c&>mlmtyz-z_rc; zyr5HgpP0l8jXJrwuqb(sq$5|gGaE;f;IxfnQ3>3OqF~b>hO}2 z6JRD`Q`W*>&z;&NeXzBEh$j6h@4-sB>9Xr|2hxM+wuo!8sm{<$lttUq)84)3j_8L>q(lMfOll$h`3J^;hd>UW=?vPTB|E zGr6SA4#zU2K%<>Oo);I^%96*cL)_7=u*&Vn&&P4P}4<{MVMau4XSp_N1BM~!hoN0}az7pOGZ zdMPgBzbI{5twV0RoEN@^-_y;s1qr>*!Mu6{+LFN774!`OsrgpY{#rogapGUbFKT(G zBm3-R5I}3d)K_Uoc+vZD0{)pNzy$U0#~0PVon4jIF<5Q6fv0e+Xd3^lJRE~keocpYx(%JL5t@L-|CYu{t!;h+^6c(p^W9ZK!7 zlkL2k(<#8?uur%qKE}nQDY?3woc6LZe9`>vM|~Q~0OVz3-N&h5yM3n@Lz+f~Wv9T+ z!)Y01=(*zn=Q@d(T*{UZ<;PKH!=G+fBdt3eEggGjjv2cjxMd_3SM^U8vtccOV&mYI z0&#%mZ%JrCAkE=2*}cfi#MB~Hy?&7SH`=1on&y$^`K4X#xeO8@bW4@)IC61eeg&J5 zbOd`4DHFs{2<>s6MC%`FpSm=kgNC#=8|VcER$H(uM|N6wKHdU3t~{^W+-Q!>l#L89 zRB=LrE+Ng82x<7N;!}&SZW}pWae;p`^ zO=!WZ@VG|7VG{<@vf|D|46B%MNN#?LJ8P58Zy|1zBeQkC+iCZdE;>ARCHu8hxcDFZu2;LXaSRt2YNe_EH*b z60*BEBr#o(esi*F$I{4V?9GcKjLO|%q0W5{Nj51zKPI$0zSsn2k0@kG4`;u{bea`om#q=%QVUs?4h)3pZG@&QSZ9%xNjFeik!RJB4# z=Q?PkYs>9dMr+-*!{BCpcYOq!X~7*E%kH7q3HKO zg2iSMT-tUg%IY_)SI51;(Y z>itpV^S}L~mbg{FEs^NDU9}To$Y9Jhi`!YUe)AilrNt;9;8uD%5=5 z#(^UgS9V-|#S}l1-?vXZt-7vnC5;1-rY)OzYe zGJ#)o4{^*7GgW}fg?>2IJ3{1rPAIB4sN0!`?fy?iW^(kn^H84|78rPU3`;Ca#M@;Q z_Y{P={=ocdkEb!!dAQfg;@J^OQWy_7u zCEAm;U~QOHGI4)cee`wd=ZJsE=M9(W+rDh@OlQ`z4$4e--Cn~=IAfl~g*QoTIJz_o z@TRV!fyHKGa>LX=^Gc0!yjIiEN%d(<-{tJmx!t-8`OoQ*>4 zJ0(xRz1OY@*R`D~aQo+kyFoNnBR(C;c2RLs;Z|?M1=;V#=I!T=S>9cD3!<_v&TU)E zi=Bl-Yh8*0TK^u~d-(GS;+CS#_MAuR^xlQ~%j>G0>0a1W^xecN@$vFM(dSLq{PuTJ ze$J4dD_vFv*?2W)JDX$_lR{w+IIrrH+|3(5NDNUvHYu?q4i9+dGT zTKfe@rv8J}vc~^y{sci&{{Q=S^h`_$rW^?{5>^_$|4ykuPd&0t8hzJS&f;p-3N_rN z>@td9se}6?tZMHPE`C3XPGuVmre>y$25*I6wtnp4`}IOTaXy6DWlekAZ#^0iW&J5z zQd^hIgJ!yE-l_rEpa#U^?IFS!yFs54%s)ov6;fA7dJG!3)W4u+R3bw|8^3G3TLtxo zo&<2=%!|~kNjBcEH`{fqG?$tu!e`L&h?KPXt=@@h-KW+kcy*Qza*@1CO&|quh8vn} zDSM9i0nKy2*_(QAC5-5HDE9IZOTL;%Ip=pp;}0*G;3`^|xbF9#xQ*6GIS}BRycva| zz3#6h!cbl>XW?eT#U-%BTGXG)B=S%DIWV|lfz%|T-cuBwq5S(?S^YiD9-poN6N?#a zeyUdg7tz2uAAEy)6X}TP?ShYr2f%n+T>Lz98IUXYzQ3)sQ}Z-uS{cQ>TNsfXW>5sd zT@<+N0hAQ%U10TlAa8{(E*9AjgUGRb@v%)NhI6OGE}^)VTRy~0nAU6?qI{=Ts^|X# zaB#l%TOc$``j|8WL>#4w~G&d%O688{BcK1EJ(ha!R+YQvi-L%KTwy=qIRrq~=* z%n%lCOPq9e#GG>B)wlQ^I$_sSKqidU8M*1&t!%oV)j&%&bZ5FT@Yk40NYCwPw}3u* z#|{~NFew1!Wgk8FVTrn4k1asI6f&j9$o$)Sm4v0xI0mEt z@MP4tYS<-nG)cC3w{-EwRr0dYsX(uvPb5&+viAI~omq4d4vv?5pXhjR8wnP}g@P5= z;5QNO=P{qnKu`5*(B_8+&2Bfi;USaYY&$INO--SnwQOiU_R`?be?imgM%n#Rtr*yw z2Qj$Y(U4{G!;k3eh9KIX*GqrsTXT1tkrTeQNFk`ghV<_b3ci+E=r*i_z$@1(oRlAq zb)q}}t999jDZj3Mkvy@?$svQRCg+zcVW&ghYWh`By-P`9m=%7Cs`0|cvqp;S0*6a~uuQh6 z+k?KkB?=;`XJ^iP92LdZa|-w_PN?1B$ryN&YaH=Bi$w>C_%lX#mNe&2hrCdpUZv4M%P zefJPmGEL$QLi)M6 zuZ;*R#jS^b9+e2!>3{wuKiNKH&7oe=5JW_jvR`|ZeNn(`_gMa+m7+fp7JSOBUK)pO z<2IZ~TJ&=!(?H_PbbLTgEo^+}?Lvjz`=rQ9z(U1?1sP92VQkb8_Prkc$YFA`dH~4E4Tf^I#bnEe?eCXk|v-M zI#{;ow@7)|y(gjn_rlZd9S-*jo-^4OL4q9z1h^T*4cPR`i~$-`JCC6$dzXnWbhXHT zf)@7JP9lR{TYG$Ba^Ejv1yKUNlOn%>G%4Z>we%>;eU*B+4yR2g=X~d7!UXROJm=b$ zw>unYC|bupyD_Hd&zcc#G=eu!%DwAw_3FYNwhQk&e-E^V?r#Dw^=nRo)ms736#q?& z1aMy7ydI#YNz=`Mn|EO~1y^fe(FIv6@#J5Q4O&K?9u(gbP3ac|82?=5dYjmMcdQqk zP{Y%SmNMqx)TH=f?$Lkgjr1gBzu6Dr;WV|oBqnDDMY-d*94W&w_mg(6^=$g47~Abl zyT|?Kxoh>|Q=7^x<#GP|tK~_V#e9(Ui$s zoyBonj~0Av=~jE1=!IpHSGn$0`90&*)qvC2x`Wu#M5Kh#YiQ9aI_R*r`A#@>3d#OE zL#mzbQ4{x?qe>H!na@W9qW+8jpqG!L&-7-EJyQLAsz<0x7T4fcfc31f(Kb~d%X0rq zkKvv@;b&phw0IPAxf10XSx>2LC5;+0JFmq&}A zP!+su2lD?OO_ZOkX@y%?)(>`9i5t${5XIrgc;tDStcpUB9KqOffo1?@z{Fu|R6q*z zcK)lewfg+vDuO!#d-;gl0#Eh1D<_RD|b82b8xv+#_PJP4SNArd& zV;a+73S#&tXr7Prs`62U(x<$a11vKG4L1d@0?>)}T%_lGEOX;+*k;wHiNBR@1WSG* z43f9-{|cDQ*scxQf1A0!M&#{Qh9cqTZ5wtcc?M&^xelp52ZgnL@aKH-hR#^w9H62c zL)zO1(7fke??6WTw8Twh?TsFOiUg@) zaA^nl>ez|wiiR6-78U>8Y9upK0!$LK2m|un66BqF1Xf?$MK75j@?PCIvdSxJKFvR& zbC72bkT1jBXf3RQvE+tVp;CtCyBSLn$u&U8RKNJ;LRSy2zmF!b6u>mL$LgkKTCmQ- zdkL@^9rKCHbN-9zJr&FOO7L-9LS4-r4lX;nK1y|bQQ;jT3BcKDA#v*jW(|`#-Ulo= zVc!7sq)RO#nZ%P7q&}0u%?hWZvrd1i?neJB60`=WMM$mvLN$FEPG$mRef6yKcFpnsx= zAF+AdZ%I?#StsYkyMz!p&lY|=vPvE7uwVfyo{;{Ft+~c#s_BbCR-C-v#I;9;g3pIf zj)z*bNRSW3q!w!}_G)@-y6W=yvKnBFq2r`tv(yFh&Kmc zkEc|t=%4vP`EtxYv9K#T=(qmS@_*&8@_lGE&fU@UC#nVs$>CY*N0vET6j!u#BGQQu zFos*rhS**FNes6-qTF-k`c>YZBPAHXOdIJ$!s}?gheyi7nuTY|eKE-A{)ieC(|ZoZ z{8=X(Ns~eCZGpVaf}(#QleJPw{zaU;!mZhy_{+GA}2lBDhucY|~q^*gzb9O@4Yy z==bQxST@?bK#N)=LZq+;kG_~4A)6Ue+iwr(oViE3(##gh72`y)23wmsjW6M_i<37+ zlvea2O?!Pf$ZbO!WxI!Sz=O(IeWe|toj2}54+_U|AsC~AS)9_&72Wj-$Fd~I@lJ!* zOOXC+bA`%Ik9eEU?YmA5GfvNmgzA%*SFJ5J8>g$`Bl>%UFLQ{XXo$fY;%B$VFpWEW zahcP&taXQdn#_Gl!^+^VE|pxz4%9zVU~O0PPmRiR{Zi1O2J^v61d)%gu6kK zTT1Bp>3kGm7~MHK1f0j+c_8fRdpnnSQNU?~w>~ab5tSx+z zf1-XeQdLr`^%3qAm0;utiJ`nY{BPF#Cw0E)MvtQ1h27~*iIS$cy-dHo57ActUP>z2 zud`(zQU6Vt084u0b&7_xi&arAAR)^9(^xE1QtcyL41yORR#1vyU6Y*LK9ltw35Ix?~^9!gsotXen_dd|AL>A$MF-= z$$XFaiOgT=b!g&eBUu1oM7EpmMZvz$`8m~IOv%I@_Fl)1&VmWHAAXMKR1xf~Ssx5L zFRVx^+dP|vbFQH~pWM;gDEju#LBv;#7d>TqodXLW5^^ZjV_euoJ+U8Q;p3PD_L843 zlv2z0a#paf3nQq5M;?7C@Up+p4a2e4zw@1l!RfzxaFkp4y>+44(JbL1j;eWht;H7p zw?1}0K~k4E3S1t#hRIR6@$+^ZmBUhxW!>&*5d;>#MD^cl@P`|}^9tSRQG7s~X;%xE z;L$wya5akN3g(u&?)n~{(nn_Hz9u)e_rWd7eq7!vN z+M?$Ro&Y0$wC4Fye&MOhHyK~EbTN_ zPrA5I+XmYR6_ka5gqS(C?BseI7dz^HF;GIxmTXUEO&fjh*t^pM@mgK|N4m6n4<0?( z;D#jhq$8jY0>e~aJu*qGvd8u4Fr@d03NY;CJ+9Wtnu5Ku7`icZkRT#kKZIOEXhnlt z^P?C&3Lm}cXGz~=7rhC9n3g*Jd*)WmuI#@Mhu}Vl%By>wIV9S{$wNs5UbCJk(J)m%~C~&^XMzqHm=Px_>(GjsOm;R+J1s$#v z-jQb2GMeY8j*72VNLds-*-TXd9DTe}Gt4dxvOOwibcc+P`|OYcq+a8eVw>AIhTUr) z5ZTtix3hRLxzXB?7_tGCX8p=Fp&ri0&kosB+uq;DaeJXfZa62iZ&z~4GXf>p8F8+J z%^L>CFyyZkhxa|F@OOrTHk%K+9Ju$8^i2znC_5xl_(YCbAne;jOL!x&j8ZfzF6 z3H7}(CNY1iu!-n1#lyCC>s2@Wg468>^f_Fn^~M$66!Hn&uVx%x zXvxTpBi0J(Tt+Q|Yi%jHh;=e^+I)%Rf)DsK)$x2O=w}^V{)ezGy%1X`j=M zdG)%J{#gE*6AUPgQdqJ2P|P<7F!j<*|jm5&zZFaay*u;OJn-G^*$O@@e$S zBvI^T+907H_iH0x9Z#aiHHf;9wDB3|lw4 zk0b}5chp&gZ~jk}bZ%*O6=(;0M6_36l_soTL>;oU{5FeZG~6zF!C6hxV(CP@vq94D zBNCn;K^T->%^K7)r<$X43FM~+i4IrH6DC8>95rt8MQ8$@z9fY=;Lr)m_qi6#zjT`+ z9SctC{>oEeQnT$08}S~0X}n+lQ-{MVm>5uhBU0xod#M-uA;+a{MEH1HQs7jN$SYbJ@0K8-aaV=7KR!Eg7%1URL$f0UU-W6Q$x0$3MFLz;mZ4dJn!ULvMn* z$5ks7y3rW-x_Q6)QTY_|{k|G+BTugyJikbF3>WbP*zG&WGcJ7J^M*ohe|awhSDe3h z8iO=3YYZhq%XiU(&Hm5f!~f{(?z==B#LK@^#rxKmebcAHl9ud;tIKXnv?@D;MTnr! zPF&yZjQ0T=+CK?Ja7^YQE})7m1h$4y{j1H0im~pl&9&G_I}37eDW0(x@BXB^?Us|G z7^4_2g%oLr`A0+6T@Q1c%~OP5XJ)UN4KE`oq5@%T$;^$a21zjr!c5I7!@g%C1T?l)^FqnoQ#f&F})ivCIL`7fJ9xjctt+% z#`BeV{WwL-Bge|{H;!AK3pM8i@koVF67@nX(PHdT&Sciq$@<3!ss=iL*kXSu?ffjK zB$M_RnC5gUWSiraa3lbS5UB7!Xzssl8YGJS0s=IFQz+?33#wmeS2aH6vF-+Fa7*5%VJnk^9JIF=X2i3lWx2Bupti5r zLpx-kz1!!+AA90RMZi}~&5HtRh}p*v$&0>qDvkQ}92V)4=@s`m(Q+X~2WEXImAz2U67F2i}VY7fl1woY6U%YI?VR->QCknxztRFApmKryud8Aht0 z-+{D>C7AXLy7fSV1W`R>>Hl1C8tsa{U$3nRp5Bvl zdqWj}A0PSTO^JHOyc4ODV!ifui08ETJD~y9i%XclW8&8f&qNFn`bzkFO?+0PezJDs zP&lk%xNK_q%uLP)^gISTI2#EB@&}dkOKx9@H@+r<^8q;!r(dr!Uv>>>;jCApih8==>pG*F!{{qQQ2fBcut~&duDW3j zp!?G>@A_I)B71)@ACv3%ikJYWqt{KO86^7RLy>Jg0_%wBXlINLA(%wls6o0%xts0` zosB5%9ZYtE*@|8xwMEgabgcCELd@C97V>eC!|f;tZ^^KQgp=$HV5+>|`@DuWY@~PX zh(CUuSruaDz6y)Pf-TEbDRE#fd{j+KEES-@`q8;b0y4bl%FOoMJnLc4h1!(UHY(4M zx`g~+DCY4SPQZdF%`wz_P9Em@aoky-Xn6~tlKEg;!%nf;Q|SkP?N>cWF{>0eB_4Ew*sApZl+bSWGq&I`vZUmlAuKD zu^APd0TFoPr*xhf$DsSo5r3pqLYYKN*_`z}*eHlwWRbKyYl_9fqp1AG(o2&&NO?x) zuGKI_>$XH}s52`qdG?&SjFuQ&F2f&aS`7q}uY+_3^5-91Pt?GX0BUuFQUiH+Bx=m0 zGvIy(+y?w+iY$FGUcn~&HPj}nF0dCB?bT@i;snGM`LF*IM~wLwV)n+Y??PsB3_?4| z2OmN-OTH3iS@-aDYY43xJ;KWH+xKpOUlIXwwKYIknm?(8{@=f88KXb1t}H%zFE{5@ z5{46p6frW>tWL1Q(Ddm|xqiu6nNdKIGLYI?%R=I2a>=Hn-Pyt=)!$&yLYAIT}#tGq|X4n@2uv)mC9`>ie-M5(Sj?UtIA z;ti}oA??&&v6dSSu)`G20!``Pobjyoujhzp;pqx<0%>k6tK4Shyoj$M-hAb_=%~la z;mJdYK>h2quw{$$bAAB z5yP4!U%iS9PlZ9XmcC(LS1dT>B2(uDQdD`5_wf6tO92;*V>@-`q%_J(G88PXwWAd~ z4hpTk`;!~*a`yyo|0>X)h|TC%8_^i-4L3gi7Hm-tuc2+4A`_Txq=_$^sBQFVLrb{8 z7DqR)E`Yo0O}6RreifP0tm@8CBU|g2} zH3`i|$Zb@ar+e@LzX|DiP8-^zia*rSjAGEL7Q*%)sn^-sn7(C=p9K}UAzgv{5Hkg_ zokRB;9d^(K+|f?4=(hBAi1Ik<%n{Og_{a62El7`Dmm)r5@o+u$C^)&n75D1w?u2(N zR0w<`!f_CSuBzv?z<+He`QD__c__iyc<`Iw^^i(+hulB~= zw7z0ugcz^ZR!L7br;Vfe!3YMp0}GI<2+S0GP6S6~Lg&^zw{T^JLkRGgF@*rc;F7}Z zFpM+yH?V#{4RT79k2FImFM(!GtUyH+rb;s>ua>V0$mqp3sUU+It|rZ9%Q<}mjGsMtYD0U@k|t z6-IDY#j!oK@UFvy+g{4s<});bC$zg^9hnttI&0*!fXx0WszvcyvsCGmK#&p?Tvqj% zBKPYi#~+%od0skT2e!_}W$sx{RRi5 zcj)$C0On6BS-x!ZxaVjfPwPRAtPYDUm&$lNP%{z&ta=zM5&0rf78<99V`GKQ5jJt> z`Fy3#3za!VG`e7V_k1oR^kR50?`CY>E;7xcem^2m^3xo=Gg7WQXZObJ&DRTJSC_r= zz8UUE9C|O@y1DIC!p09?>45IzX=@FvH#;IDgDuF^0NqF`>- z_CGp#kA`*6a5CH>8`DT_3Y{paU0KW&lgQ&j-vwT5WV-S8NrC1KNl$iI5A;3gB z8xHH7wvFgs{_M6kB=F(vCO1i?A_yK!&d{utlSOH+Jv zywaM1s{$8+QtOHIQL}hiPI+BW^5TTQbwg)}8^$*GJsb^g}0h<#ByB;pBKJ?~-MLe$x=N)m}uSVe3Z#5`4J7 z%>^^QFn}GTB=ti1NtV#80a{0zv_txi(}85lPBFNq0REfsF=W2)FvBk%X7||(G!V=% zTb!{3gT$q`GzfO}6*99CAJUKHJ>^6d?Dh7>tvkK}zo^hf+ncQV^lPV$NBU-{~9x9E;2Yc94!+7x|{#x^Vf?5${>j#kRo8I4NCOME&WA?<+FelY&E(9MVtc>wgvoqG2lHg>^P$LlaarO2A9Axua$+PmLTn)Stpp zXmWloR=+xZ?{O@m_h3uUVt+0+-2;ae#UR(G=X7217c@QN-g^+%AED@~_GK%+MJ=yE z;ZfPx4>n)%Aybhe7H=5muL9=uygmA*2=GQTWg_dNHn0Nmx%febR!X{N^0}(!Kvxyg z4J%Yg>FfUfhXKZxREiNwgw>vNZ@@Oak`lJV78pbr&UX zRiCAsYxr6!>HQL<^>gy*%Z;LkYKnfsQIq=k4tG<6-KLIqXcnH))C4fJnsOKMHS4P8 z263s<+18vM3Ch`);gLHvcrU3pcF&h$BAN>~N1tk2WH)H+ zJ|09+?1YUqnb_ne!l>aL&V6P7&kJDhijS%3#>^)M_TQ-kgZhO`bP5*DrDA39iJlDO z`K!J?{8u_H!k6f5$FhonO7L1>`Vx=8-&+XV=~|f3$SWKQiIiD2Z0Q+ZVc1I*b08IV4xRqJ;R(eddF-Z?uuYn2UFW6c#1)n*m zO0hEkGGKdEQ}N2zqFD15g&9L)=o`kJ_C_puW6YYYoAkP}*65SiLiw0U2c04-H9u5s zhIAZG_KR*g=rm5?8-pHGYn87J$px@om|MSxg>6TS+MDa(E3?xx3$+Wbu+Ry>EI}KH z99}`E8vj!qz;1EV-7Kie3MSa$WVPi+CUTky+i9R2&*3#qd|~GC8{tq(l1_#Ju+l5( zY=ylfqjQW7(0-MpG3Ve;_LC6qHJL%EEW22 zXId4-`*lH{Rqp=-kw9+0{gEPC`*X&3CtzX@6h>>i%1mjDV!j+W4g;>NJs`ILqUI__ z?BviiDM0l1*4&SY-B{n>nv)5xaAWJUn%o6I3<>9{%}Z%}0v6*V2@F4Df|rUl7`&+N zay7Odt?N~LM(|GkEy-|Z&erk`z_;`%$bda8_$7wTe+$zUpvbRIKTA;DfHSdfZ@<^Q zyMGb9`P;pi5#7K2HWBs1E}A=|lchG`nVD0QjMH};1M{NY0km8PQkJDlu8L5RukFTs z@(N%Br;N{xviA5IptLTJCNMhwtr+ka-;z{ALY|lJqt}>=&*n6?`dXSIYh`?DeX2u6 zRar)s0Y%B_uKZ`a%7wbM=94ags{CPVd{&6|?Yp-Eqx7zt&1+F1YX_Yh_u29n-A>w{ zK7Yr|tCn#-(EZWANM>ivSsPVXseEO5B)8;9?5}^^KGQFs$6R5o;UcOJf=U8om0pCw z%p=#3P9)RZMcn$Ei9`)zhfv*6(w#8OZ z)U7q#t#j>2&bAIph`+f7{CeFuZ$(zOeop~-*#N5GRMP%~Lr>LJa-+EsWYfMM_ZNG& zDlD%$X2o>&Sv^ZeRX-o6^qUEl>>LFb}yL+r{uS8rxB9yirB_5+h`Q;hk{Rq($#e4x6x<5puX|=Hvef5>|Zv-fu zsPiRS(x$vzxSz<1Pcba zhz>n^?t6~=ZwSt!f;X6sgRv_)ZI=;c>Z*c*dpq@KE=qqu6J&fp1w1vMBHeQ0KE||k zQXf#IKg@rpeAFs^$MOFPxWzgx32Q0)((>fbNK1#6iV80%sKAN2=iLKn;28<|6bsXI z04U$4f>&lvrv(@(V>M|!+$e=K%#t^!;Z-`S<@Q&ugo0c8Z< zV~rxQD&4ph0UJwIAi-%0Xah$2)%r@jZS1Lb`=RWXq$xA7S*CD5#4&m{n0YwOMdEB6xu%`=Sx6J>1mc@XGy z2{6wT?AEReU+J=(D1;1ZUI=CB~Hy%b*u2jji+cxwrMlD%CMRZgZA%Rbf) z>uZ>AbJtp3fMQgFb^?tfV|@C@j}EC9#y#CM`!E-f#`0B%yy}p@N;;$^_z|y{ZT|T` zArostBcBxF$;mGVW5R&2u!WddfwTN*VmipJU1sDW4hgD~$Y!EA?*K;|@S3RxK%wR+ zC*T2)xhjDcn}KSY#uv>tK^TN}0H!N8?v#o5Fa9^H-}rNWaP>$2o}at=TYmVDt$ynt z_#>--^1u7DtKa&!6Y2>|ps51)7tydm*^#J(Rsw2I82iV2l-vswaO(tppj`8<>MFtN z>cp4IY5V|4-Vw$Dr(21h%R!i#>Izh3(hF==N~}7!XXe)DXF$kDc8~e2IpOQ?W%U&b zFmnqQfWv-~oEQFOnWFNu*#KPklf1T(40e~uIF^O7!K8W#NTS4V{kSgjlm)u zPha~c>;}{^4{m_FK3n8tK0!+kzQ(RHf|(Yd1SKr~X|bCD`vQUx2Xs_S83rLxaQ8hr zmEugHVw&=k!d93duchey3AkaV#$!|M>}TfU{Y1+)PWog`89nnUs?sRLSmc18uVuBT za}_AH%t7hA%IvisONVg*RPwF7eVPB5y#oZ)qvIG$ZIcrFP@lSb(Xo}M6s$hBZYE0B z=QH^|16lX(KVvcebS*F=>HQLTk1wUQ5TJ>fy9f}9<<6|QBrLDL_5udD=U-m}G;pQn zs(sQnYDQD80t*1JS{maPn94sd=61I!+8-0sJ!UQVCSS6ina|n=J9n}lpHG4`Fo@Un zUoyn8k`jLdUa{{t5?dFQo8>q5dCD$!Lu`N1#$BaJsrGP+vo%tVx|rR}z?Xx1z(rK& z4``gKZV{a|>0|szKy(ZL0`A)U40r_?m%cQwF8eDtj1`6{ur_s#=MCSj#9jc^?*)F8 zgS12A_U60Eq~%axQuN7vt%=HB-dINhll|`2ja`8+TD!9b*4APNk`7K)0ja#>+5NjZ z7>DZ2DT1HSwlQ*Uf=LXe)jCHy@5JoORLYmx^G`C z{hbs>?y=|7cOh%qndN9VGxM2stgAz1>uOWFBZ4lrwj)Yuy|!oajSI%@`0O@6T!HNM zBW7~hKE@(u+<|42&yKa!;V&?|wca)ky<6)&0Q%!ehrB0;N>^2UcJ3fM@+=pc6FKv$ zLtb^rUo9OnoA4w4wR^Vt?tqxj`&t)-K;Y-U77$3JOcjDr_)pAk9L!&$P&-kNgE-b| zN?nb7rM#s!d7_;51ZzHCkiY<(L|P`50W^x5eK8re=-4H1u6xj;?5Sj$m(4UGH!EpQVfm+#;BF!}d31&why z2e>?UN9i3N90srlXYp;V<=X2O3N;UKQGr$=4aVsb!(_L$Fo4K1gbU<}Xm)B^G z0WqZ%$?^U^zaZdd225u^1iTEqp{S>-jd6&#f2Ynkd#0SoPnaWZml zpCAt%}_;$p~_pb57Y8$6Uup>$y2CdN! zSUH5a!HngF|J$;UbA!O470h6r4d~9yZSBN%22&5_uI+lE{O^bHa-Uft=FnJ9B5G@P z%?7z;Q78bblrdFE35>0_-|64J(?|s9Pp0ufh-^l?j*OU%KVbM&oHkI%8 z1E6%5%ut`Vlut3xUTvRT^N03d`BsZ)UnhS7v>N|e%>OcN>{@K;f`3`K6G7A#lfZJCzT7s;I>Lx?&qn=JsJCxq%j@=_3|v11P7awq-)52oBo4XL7xmt1aOg z>`vTnxPVV*h{0*70Rsq$|1v-MNW=QB5i2_gX=jy@k_RAl7@le`3v2=BA66#6e%}CNQxdJ{QDAg2H8y4r3jSU(g^sI$cE1Pq@6hwh z7#p^b4d%Vi7HpEq?kYH8o8MV}rT}p|&=2NWr5S7W#eR~1{emRn0Y<3=Um4RS9O`zs9WX(TKbf%!Q=mkHJreOf*63M zDT_$X#B3Hs_HKM5xmN(7jq4=2=g%4N+c7Usvfu3&?HT@t2LCSil@4_E3rn@lg~G!+ zFvL=MdG<;T+*s!uB`S@|JiFxNeW1f{`3QqjTkB&J?LT8>{_3|>GVQtE@9M2s!i(Ud z{CNZMr`=ogd2>Jp8WeCg}#U>gW)e1*QLfJn4{2 zhi%r9MDq=lz9d@ri}hNG&niQm+wbITA|YSXeQV16WCfY42ySneg`oVdWpLQGz>V$N zT3A;Glnl@Q|EfcBPkGfLe}xWNj4sQ1`UrogsXqTJkm66y_vPP;?HV>_G+$RhxRw*43xK{|8rJ`o3Sa`s+UX zO{<^$?oY4&_#gjt^{f7i-@E$$>rY($iC_8CSHI;~{?O{b|Jk3d{^0QW# zU-MG|8Uk3q-vJZT<GpXvb| z-nY+~IIKWU*D-Bp&lw>FoJ^IMa+r;YtABt zqp^{ho>Pi-VgchHQr&oQt`ETllUB#-+`pK(3LI$V<(qYr-OAUCg7lDi=9L+(vWJc9 zlvJZE1AF;Vja{0^{y(y?BWr5A5^zzf%P{u`MW+sa{T=D=mdz3biyng=;dm*K3 zZ7`z?yPEeJzkJ?KCZ(s%s>XZ;&QDGcx8pOZp}vGFSwy(!R7y~WZoF=9g-%12RM9h{}c>$17Ms^U$y6&H@lMCNAq)IjCNBq8aQyf zT|o$x-F5xNT0Ecapwf3b946pn@9JNG*A1sHHw8pB(B`Y8*^P0~zm!9nB)1&|y?ert zmvgcN@f&OCJcuzT58xTNC}DFz?BP~r5$iM)?xj+U-G{j}X>!KsEdMS5C3dxy|7>4v znPxLvZy&Lvv7Gkbd-HN5Z)Md2X8pHGyfZm5$*;wC*d25)_lB6+tubw$E^nE*xt8?a zp3*NV{%~aWZHI<+d#TI8;2i61?izze>QFi@AYt#zjnY_994@CmyMvcaYA-Cl!f}fw zrC(}wYaqE(#BO_Q+Zd4%Z|&J7u%=^!eG{;BF!amxKcB-%l5U+{0J9q`ZTURcRc<1$ zW9JPV*~Z;M0L#fb-Meq2*bLtRhRvJJQsV`~DZEAI}qahZz1!vc~4W>JUEMuR7$f&>^#!KH^`aTR!*uXX%cEJy4gq=^bZnTZSHpp(66J14aCe5{?lg_^K`5`laC*2Y;I=0Y<~QOQ%@E&Q~)3-aq_=)i3_^~In6 z%U1v3>SwKf|DXD8t6%*$5NtpD2Ufr2=lvq>_@ULW|NG&gpZH7vcUM1M(mZi-A#cN*nT{ zBDgZ`C(O12d#X*mcJj@6JYkh7)rXcp07$G?tj6|D%GK8bZcgS?VZayD5c8)Pl^o4+W|$vsenn)xJdXwO_7X~l-Tzczqy)0k()!u} z-L$=*sj>hAU~+BD#`GPd+GWn<+oKXjQ+muW*Y8u{Si4*6eRGEesSKdpoTos{e9!pI z+NV$bersJ+*6^Hv-Y5z8!{U@eW&(L)JKb{^tH@no+yPLxajJJ%z7h*(*eWFw)uV4a zW6NLDSe*D@uK7KVubNMl8fXEC%b_49>I8f|4w&m6m?*5pGX>aeY_C6p31YsT9%sfk z|9t8)7IpxPh3@ADphL?}ccb<$hYf3F`n#ClMOy%U^*QseHqZSp(ntaS z1s#rK01(j~5;C@X)%E-ie9)#@@&`Gk1g7_{}7vbtL3+Q)QJQL4fGS z<-X-dX ze{l8n-z}Hl5B=%YpCz1r^6qK%$?czC{jvY~hgbiHJ3lM1zB_*bKzok&Sbdq$8jba3 z*|wwvdGpP$tp1eO|Dj*{%U3_}-ISdQ1>gK%erWZn)Ac6_S-N2Z=vC!pDhX5#Bi4^1 zKX-!1OoU(eor02knHKW5c>p>}mxE~_Rf&|qMYr>sdzHky0EDx?N!d6)gfT627^bc9 zO_{6CGX9DLl6$VScT~NT>;@B*pI*LTm&#R{mw@&Lu&Q=$*Ce-fk4!`Q>C9U;h_-_Y$gWpXPV{Ij^<$+HY4?S5>DCNF)P|g9z$CVlbc*2}BWbpeTZxfDRlb z63~%mAcTN32SE}I21gzcF>w+n8Zrr(fe4B?aFp)quBz^O_c}aBKi}(KyQ(YpsChRu zxbFAed$098_u+s457+g(e%Ik&>#oDB0ZPTf0!p`b-srQQt}l1COp7_L;4oa}g8JI~ zn1JV)D}R=4_U5j>=Xy6sN+hXp^c5RCE@8^Ej9?s)XBJiv%#J0uCf|-?Y)v%xFbA+R z0o;;Lilt2%58KD!$=!Ogg+@t)cs=H5iiXFC zy8j(eSNP0bZsLrL)~i2H0Q_C-czw>O+6do>&A*v{vlU$H;mvU9oyS`cY+h@Eg9Z`3-j zZ`%T}?D%4j8~64!&m(~I6Bnx9r#ZWltTbMa0gK{ReOGPCy)8GBPX^SVx5JJyo92Q3 zN&bx+opBs{MyUR-(IF)s?%M@O-%W1YB;pyT*?}ui%wt7|tgYJ@VHEe`h4q?PUq&vY zE<>R;e9urlNrGC7jowfI?IGVBsJ>>&Ywc2#-l*RbWA8fTU5ETu9rBaaub4+)?l2p_ z`6ElUjNdH{a#f=(cjLqYX7X}XnC6pZ`T5Dkpgg7#V$2Hsr(8dY$2nk_Xkr3`U`n}@ zvenp%CAzUX%K$xL$l9Hu<4#OQf%6+mquN>(FTNg5tFQj=|6=v0|N1|+`mg`U?_+TO z{?#A;2c7)){ejhYzaOLYr&s^tU-;)%f9qfW`&WPC&-|Iy-}qDi+3H{ZM^~#q{+IsN z>M#E%|Ez_5Tm7G_KeGDw|G?j~+Wl>%VBEhrzw5XD;ObxbqpQ^)`&a+$>JR?qKe_tH z|DXSU^-uoQKd|~=|D%7zJ!KDSdcp1;YcA}GB_V(VE7cEMls~~rsNXO=y8_v>mVMur zZ)H+n#2uEHF-!u1au#$Q!*mH`k1vK=97UYFhOlpU5bWEwm>mK(3p{0d!=Nnn7lCqs zt1Z&n5#_-ivM29zpcLEnB@v&cKga+WEnezo&*+_>7q_)*DXdtwS1-5+R@x!vt0?(ty) z^+$?UE>1ok5W6|prxcU&AmS7yxg}MbTN{mjF#ts2sg!ltHap%^&Z>Ux3YIJ z7Do)x0qDE{|J&SmGJ^waS37T%MzXbkcN|3K9pEKfxGP{K z?F-a;pX*+KVme`CmuKK-=rRWFZyrb<`5w;vU8Y0!i~%;T`Od=om>f*zH3u1Db3{Tc zF8mMHZu5AT{vp#Uf;7yw)!f{v?&PcWad-D&^~#t$Si^DKZJBzAS)>Qwb;!F8`R#Pb z+hqG<|BU?nrtjY3KeFP>vRg|m$kkWe%JKErO!kBy89_mQR`9ughzbINFtQ+Stoz3V ze2S6qFQ#dVT>GS0r`c&E4K{ml0tN}om;}dc@kE%!PR&jzTpqV?e{1#M{Lz1D^-up> ze{A(nT>qEVfB2vNiPeAkfBi$N+xH(<|HohYldFH=-~4A*-~P8<{2%|-)$8w<8T>!| zkE?&@m;V^H@!wtjssH`2uKwY_{$H*B`A>g)_2>Tc|7o@Q-+r+A^Z)Zdwfb{^`0ri) z(ZBHDuKu;(|1Yfm`0xAkF8&j%|L#ZshTwN4ItYXWbU-Q=j8RSarnqB(a_iMryaR^k zk`+x?!?@qJSrO9lH`pOp&F6c7)26mHy)1^~(msQkLLmo14Y6of$!~ zp+IiMivd!Vp_x6IS*W>`?y7gFJ!L!x!q=2y$tUX)P5==-IOko(_Ds2;SQc#vB=m&G z4>38#%@hNP{nYjq@ES8a8H&BCLlU%OaYt3_Z(G5%Hzq7lSOH~fhq6zp<~FaN=ru~B zfP0e$^Q3(-b%7L?b32!8z0Y)KZ(0XC0z9-YWumVFS^-EsGD%Iva`~?if+e1<8COrI zps*+u6p?O{=M4P&4c>MpIBWS7qEDV9e88XmUyhraYp^V zWe@;pQz)9-oCfqe2GiJGw~PC!wx-Xon69gLZ$IopCSGHS{n#r$0B(2~ZN=D4A5!|d z6Q+X?3DEVAhxNGw5VvKY>feq#{aa!|<%41=rjT?%ML(7}a}du|Y+4!ln@Nno*!j*3 z7$9>4Fbgdx2JJ;{&3lO^g@VkkD)WTqGbR7^Zvr2l!7ypZnB8M-a151bt^lo#eOPfl z#!vGc;2z*nJl3-qVXekiA7##OoHJmnIR#7}P~SYLsk8)kblb@g4~Z~>@JrEm|J zv85bR6Oq!TlrO>nD|`6@p9ALfSe?rjHVLZ0!VA)(!5^9>@?@h z+LD-t!89k^<}#3#LD!!RS$1Zu#m-&w7!+1ut=IR@#~&I+eU#zEpxv6|7j=6s0Dch= zg^e5@@vM){;f{;}ZN;w7tO}zSciGx4PA#Bn&Xgdt!Q6K&1}LB#zHrYQkHaC>SpR3R zEoHFY7HKtu%=>w-;^69uF$gM4)BIYDzB~nG;ZJBo^$PV<#@DGenUPB77e^P{-nfrZ z7t{UtJq;>kLkXkKAryw?G%ma9j8+4a%wCLKP0?K$ioct5NHsxs9D{s;eFTaN-977^(X zi=!|ceNG|It{u14lfd$_9M`cvfdc~e+V)8@OfM9|L7Y*5$Hf+m%iSX5yaLR{2n9@1 zchT(KJ~vnU?@k00LDbIyiD&n}12oUS`75ixbGDztFa4sYVJ6)BB2er4^rO{}>{Rjb zBZZ5FxL4jI_v{aUfa%+Pd-Y4-0YpMP#nS*!#p@ia0XNLZX7!^Vsg?JgUts-HvfBNL z`)y6o1z>W0O!4G^ivK2k=1-$1rDn2XsU4rm)=J=7-8`CneTKX!*w}44aY&;!j zb0B;$WraMO?sU(ftn*XSqf`Q*2G;mZyiu;Itnv(m+`TEpKre+j2`b&B!x(M2qK?j+ z{cU|70QkH!!#cpB>)Y}y_Aa3I*{DeQi{8V;3hj<%bdQwRL+mqU8ryq22dtK71){gb z{ZOg{oCDLqN|2$WJ)3EBFV`9i>}h-d4ubX(Fn4urb*$FjWs+U0^M(bgaPSgGnR^+V zRotj#gU_J(r-=Zc+Y+MWwwoO?GLU+& z(VaSawb;A2)?yM%+FD8;#d1+-HQ(HcOIurC%h0AY>zl^TF-a!CrSWdvRIcb^?d0As z5#(O7#!{mcb0zLB0JQ~txA{ptqb>PL7Fog$nrl7vbN~AsXv|F)WBmCj*=7I}B;C~O zSjsDzXV&#(#5?^+7L^Q?;TY)204s6nN?Bj5%Xy?VHhi=b;vkrmi;c#AvRdCt4#7-znZ0=_gDX{L#9@)eh1Hgiw;?ggI6I8 z4`K^-giC)r9a5-{7bWxB2J>BqSex%U!33IOsPD}Yrj7UhP~X#drc7y=^??lA%C3B$79 zSiJ2}P>F+Fniq^g3MfIlv3Kv9BCFPw4bw)!UG4w-_hAnLRcoCxzzAa7efyVIzr?ka zGQAQ?#m?oL`rh|rcUsh*Q|}Pc3EGW-><7y6Vxi|++1T@T`}`xWHw*+J_i+SW?RWz( ztjPr55p%M!V@XE}^#TwNfW;n^CtKEEf%YrlFSkmuRRO#!hOA>3xCWrNTtvm{O(F`n ze6c7gZiFG%JYk(Xu)e1Rj^6L0zwRXhBy`&4C7qFJ8WXk?YxH0XxwZb=eC48qGd8Vl z;W};0V%@v1#D8p&7uCp0;lja-aHL>1E>rFBcK%&Wq`~zF;w?} z)Dhw+Yw_s*i-AT3OsWk7r!-q18|mgY$I)Rq7pU?sC%)XJyUZsW=Iol$aT#C z)Y&&K%@t<$!2P-OFea?A%@EMfC5c(8=1ri}c?DcD0?r#TfnL1Cr7bX6++Ir~um8B9 zdpC2fF$wt1`m-)tBgwZ|rkJ-GSDhZtk6|i&#ON+8CiXTcQj$<}CTX?A5WDZVG;6Wr zCW{@y8c@TIj2%6zZ@9~CoOMP{CoPNfjPbimu3-HG{%XJ&l7GCH61s%xz4NkSvXI%36c=EnT2?c-Sq7>>N)*7nu!1|4#j4l&lR z!fZa64;iArRfi1YYz#j9oDONWncE*3*fT1lvH{fb^gpk2C+cBZ=Ux1pncS~WA{9G5x zCjgl1n8VyffYk(YQ<_=%Hwg?h2<77Zzyl>5dlBJZEL@skG6_f0S=eIP0wZ5>kJYAE zLa(@-T^VSec@{HPd7NW0PPt+T{uIY#p6QE3YDboNj6h&lOOk*<@B`MOctAo?jLAj9 z!iJ)__L=w_-&pq7Sl9e|BJ{fWcvwz0HlXYMZp&nmMi8*_o4VVbHXrqwTJm zCzHf8V??_TNU$Lw_Nk<%ScqbD64CY3{7IP^zvt#xhj+gN3X7N81R_SsQ+_coKv@Ya zCoamnjF9PRPxU-4UcdqcJB7iuF;1&&<*RFBSwaoDnF6x4dgHS~A`ZC#mni~}GZu_f zwL4GdW4(0D@W}8XEZeI(@L%S_=?NGF?yuI%(O^_uxOSBov^RGqGujQPT7bl>6l10> zrvd!t8!*xCCR;I{DeH4}=o*g!)80vc&$?x3U7n1e4ALT=HnwA|z1s{X*KRP;C+ph8 zrxdl#yU*UpYOBQvUNB1H?5+J}eg>XnPcP356>H@ML-Y{KX#4^?w*Z^?UpFzwj7Qn3 z#*a>(@2~ntj;(Ri2nO0#qR^nZ`o@~QSwpcm!**iY+s}JBij>rl*!#By*e)4C;z?q8 zJL~g5+uY;c3EJ|}l8`drnJ;|3V;lzBV*X2xB&@rxa8Lv)|8BP_2mdf1L9r8f4!5g9~=5X!({#dlxtDH?)d6FUZ2ox~R1 zD1`mEM+q)UDsa;A^0e%&TOj-0eb5Gs0?I19O!8tx(meD`TAG;oM7dNgf3~b5pl9z- z0IW*<{YR{lg;+3>Dcx9 zy)M868zyGR4go24Z|h#kURFB+d-kl!X7x?Ay^4*x9kCS;1b^)(Xp12j7qZxtN;s_T zF&dLIib$U=Zqwetd)n(a*W*!A0o+N)0yHr(ju<#Q?G9kBN2)Nhyhuva?|^lHZ4Km% zE2lU=olx=Qz)8W=fx@Yq=!+NIdBt$`?so+Fo&t`ch!uf4emF2MFJ zhO-0Etw%OMZ<&v4%C^2*n=kF0P;3CGKVYP{i`K3$N}G&t{2pU+``;r%TWy5(l?vUj|arh;CWWeVtf4F z<#yIT6YDn@8Cl>lpj>&6MI8gf081eawX<#G4geXrrbR$tbq<}`w3>hQf!-dsYWqD; z-MdJc#y4O)z}Nc#Qe9Mr?!#Ap#%zs?lL2!dli4%V!T@q$t(eIe+yK=AS_5?q3t)6I zj)4>PhaJYS8ka4etn}D+{g4Z<8UPto&ES$uI(H83*jjf(UTaT9yUPsU&N;O;w_m{6 zi_9}z1>6U2LLFCYxO$9_fY&hg#-bR|n-u!Vumx1crHO{BzTZ+3r5LxK-r5ClfU4Gh zdsVmnVQgfX!^_cU-a#L{2oGs4-NyvC8<06wGgiQ8S^F7vMimG#SAhD+yJwF_cDP9%*&>*U7U+yh(FFd(OfU zHp&+DUGuCpsi8s;jfZOkmx~+UZ;ESAsD!aNu@H*O+%vYOZ)fduzXrw`6T1vr2JjSv zj~Vo)#la)&>Q+BrYNHv{jUP&`&&3H#o*gc&?Ny?E7*cOCMsL*8}B z&veKviZA$AlK&e&0t(dkxC9eUR|>48hg?$kDeTri;TJPlCSk0?T>>DhFqcCyDfad~ zV=*>dbWfjtxCF9OcDd6&a7RQHRN5q<5K~lEZd*OY%-jIa7mVOA4xXKo?peic<>q?A zCLAcCDK<(-9SQSXA`=wN5qVP*WJ|CmS<>xIPeg zTzxd32eV?oF4)UR0hTfHx3ciI7}|3;3e&V{t}uSW9%rnv;W|FRcpFeX=gkkj*x(RNt9L6q76oH=*)nGO_cP=G@(YfF7Vfu!71Anr4Y zisEQnvDn1P8Z~Zb$|zTBZsu6bODv-Qu1^>&%A>65wpME^thVFYav8@e=1$*G!f}PM z$hQ~=<5m{!mP=YHv@vlmC3H%mVmK<%k~{X^xZGT`rufUS4#q!og?7|Knx_SU0gOhV z$NetmXYqMK%I1fetKhO43Ld@wA}o$EK3c!0BRtGD@~uA zjOWeR@vi^$C{dz#&bIU#P}esxKPlMp)r#8;4C&iB0uKXf&6A1qbbqW&C4QiB?~l=S z;xI$rC-?cp5gOBNhMR5Z0=AM z{F^hUcES?oJ%t!lnkWEVjmjf0fLG?8Ee5S#2D)s)7T{|4hUxj-PD_t8=l! z0^Qc;XS;f|z2WLrUn(iGPfqbRwC`@^W==7#o*9TNCbPK_%X=r;q%=?cR2RUc;Zv5BJ}G*Pp@w^nHnH z+K`uHlYx6umPVg<#Pkc;^rqI?Y#~S%#V#{!s*%`H`?4QbkV zC@&U{Ag!DT&BZFlqSOzbm0S5DJ9$O<=IXk;|2^I_7A-KD+c3~W3DyGTD5$*oZ3z(f zVJf%#HmZ)Al1r!9r*bbYlxamS60n!b0Hr+i$%mm?;wpL$VV}#Hf{mX`c&}qQDKWaT z2Wy*ujbD2SkINsxCE;B!rqgo*2-Od4J1aK;Hng}hHh^!Zh`)@HNx>>U-bz}ZuX=8%Qj$PX1eba18s`Tb_KQVwBJMXZtUB=Y= z)^||EeAhn2Q+p8jjgdYZLqh_L0tanut*zZ}9pLouxSLIZYSwwOK8?LH&;a!m^)A@H zIp(U{6gLJGJtM}pw&)NF^T)0MW-ua$6F>oICf%vC{j|TcB<7P3MZn3SV-PvTl zYuz|ryu+Q}Kf52BpL+l?^%+VS1Ew|(Lnc�Wq1wZ_gXLy)D-x?d9@F@__gBJ>a_(>>pIC7JA3sOx12nwe`k+l z>;7;Mh+TUyu>*XPTaHF|*LGv(y=Ci}OWBbCaL2y2)cj9&kaKIb7c-z{uXN+FmB4i~ z78#AE0DKu>YU@UBLe~!{PBxiKm%>vdyfh&SqiDOxj$+xm{Z%c-4TE$kUY+Yb23NwE zdAiR?bW(Cd{DNm{OA}iqhbMsbgZtnzdg!wWD1({%}qI-h1t$5ai<6Txdppa0UWB_7n zt@?Y4KLxs(bbShqAS=r)aM^yy7l3D*Yt}u=;7zawsA3TVduKqPvLg?69Z8_X__g0_ zN~CSW&PntXcw%wb2#yeKfCeTGZu3GY0w)~D(;p9h{s|%VNI+M_`5t)q)E0RzS(mYi z8R*RY#rL25?)(eD@SxO22hZ>cuq=c#Z};PLI*+K?Q|N6umolEB*8ugIqOXlT{l?(w-+;!-?iOQ!G;Y|b z-e<2rieD>xw0(iMT&q)45E^~CD#>I9+=+c{lD&${EW{y~c1n0HX0HO+lUSvYaV1rj z0rKn^&{65lO>8wv`0APM26459Vvmc3+yHpfxt+~zy2HGll*2gy!dFb{#yUa=I>)#< z$3UAOB@YFRjUi@l_FD!ZZtX~)JZU&hR3bC_=?%unM&&7tmBo8j!4<0ZV* zp2Z;1cH{BzQ8^=Xpzw|5$P_YfxUS2ptz=B{BLir|5DSbfJI0U$=HxE6s|hr#b4JBE z#uKPYF5C(&amT9|=L@;g5rcl51QXx2&7byVv>f_p$7!Ab06+jqL_t)75L?PBnJ3QO zniGM`5|bv8O55tyDP?3$2l@ks;~LE%%kVMp*XH=E*wm7LS|>AGW4m2ja!I^k#lq{K zqa9^-3e=ArtBbnt{G%v7Hto)JyW#>9fZo+mg7>n={m?up0iwNkD}rB76ccSK=%-ju zP!VXW9^v(>Y>MxnC6?8mwK-V)?}@Cq|A=X~97=d0d7aBM!sAhxitWbDb%q?-c~5XZ zn**~aHl}yBu;f|!T&z7QS#sCWJLV(EEkAoq1CJT&WxTfyW__7FDM2bOF+0!0Jh%40 z>yURH@~%S``MQ*qvO0bTN5bUupDyp`WZ=&}ORIe2N37cpYt!~uXca5E?b3dckRX@| zzvmQ__gp<-f4s92WutITd~Go(m9mHd%xeD(8e+O~5d}~JWc2k6 z#{_ccPIB|yL^o|Xv5xmy`m>7xMi1jrNsQdPPx=p+2E;7xncQe6z+#8NIZ#4Vq}lz8 zg{p1q*hlwYK)9|**m~L#8}tZRPPT2r88AEm;laOPVTnE7!kKSCXMWPfKuB>}3G%$L zWsC2m1m;SN%nkImRaY+QnPgbPdw?s*T}JuI&JVhAfY!8$Qh`c`VMxKM5tMeFr^RRn z)TjMEDz^0YYBYU?TN8lxHlrH_q*Li`q`{!2rE|1&#~6(6kS+;n>1K3|E{Rbiq`O1X zk9&XL{UgqE&Utgj0PqHpg1<>S3_pEOrLnF;nS%) zX_RDd^Yi*!d#X9BOMddyZCcw%8s%zz8xC6bmJq~fKQ+3HOXNPcQG7r;t4wR~%XkT9 zYe5$;nVpi9?jPcjocqV|%wAx#ux1DWfODHx;2sVS!sy{>`&806%W#?roJSt)RkvaM z3BLKj$`n2q>RRRFaq7OWk0<41aIvSqA`{JS@PSJ|ZvIw}@6jfdSva7>4*OY~ezMk# z@_f17vDd!m#i6JbmbKhs1$*>%F6PUyN?vG&6ZElMZ%LeuNq}al-GuC?9 z!Yo;94nDDJX=F|*-ps18UNZ;U^myb4%nuAF9@nP>jZg^_%dG*bR9>mj1r%W<(=eN1 znIxp`2iyeGOP^>D&i*11*Ki+WU}U3Ef{6k11ULU=E7<_K^IKX;WOEo+lhg_OPW7(} zSh7mK#~&U_^qr)d5Ki)D%Mg;d^N2<#F6B}=^za*o&EmiAoA7&NMJ2Kao~zci*lTLj zTsvP+BbU>iS?U___D$@MBz~1g-Ri9mXM!1bK4FOMxSNNMk=&hax~CnWu-oahFBxi< zoV)?ZznsDh__=JIXS&+HxFraO2MXvRVxTI^yg@I2WgEWFJiXKmePk@R4?{}V`8(~? zw>0cRmg+({y6+r=?C^tNG&uxKJ!}IUw+3ShV++LiOf2{nhlYXg90o(6u|u?g8hR&tG_*YMBAUPY^zA zw7#4D?QpkvD1oWZwaOcx9755?faG)cTx&JOkZ(8tfQ(4tb&8r(L}L;V)4-OpaAF6f zx8sM*nuK#44r2-w@U|wrJa^Q4eVK!6F;98%z?+1G$vF}>l zEtS9Gy8q#uzXH{{y*z4~wQGXZj44;yhzRzRRz6eJi8Y*GQs&skXf32pvZLnQd`u*v zZ!Y=hkxy#V@;03&S}nTa?DfJz*l!G*xNA!Srh4m1LrAGKH3z=o>_JbCQ?TfL>`mR`jyL&egeaU1-&3)=Mo zW#rBhhD7#*>VtoHGu7kfTV_Y`P{ubUou-M!HN2Y)=zBy2()84@QBJv+uO$5s=A(`I zWx%udH$E`vo31=5w$f7%zleofA|)^k2bnw^s5AWPT^B>Hu&)8Qn^18%ooRWVP{v3 zcU%fw)dR!Y(GLWV_%U0+(vswuv!JZXce(I4w)1i;1Z^$!2BQC)y?|!?jG}YcvwqGE znqwEE4M{Y4a^hX<%RzVC~mY4dwRh5kFQiZN2E%i~or@)VG8c~Oa!YS|8{*K2tn{HQ!84DIe(fJMPC{hS>v!nV9g^nO z{d&}lMp}+rKUdZ^1|w_jtx0>Nj08UTsg~gzFqD}!9sER^oQqWIF(m_v0@qZ?beBk8 zP5l*#n(tRD?uQ6#;UaCUxNBFnK|q54xN_=Kc~B@Ozs}8-zY@xp{_Y;{&R{9C5dSMm z5cbU`TSzFg)$X6f)3^3m@L0lYx30f5mvr-75DgtvDn&msl7za+GaG^((SslnaATvv zxsO{!i73+3yyB780W$>M`^&NHDb=W(knyG8x=7Hs(;Q()^+GElQF~pYYz&f{d9cEw zORn+gs?e`5J7&l2UqgG{=xK2(stI^$?69=1zjklynLbOb`)bnIWDLTB2eOIF2Uc)& zIbbb^b!6YxmllX8b-_cdv0Ft<+Gi(X{@7GLBswQNx*Y*0(ggn^CI3bp-g}mu@@Qr4 z)GxX1%9D+5urb+xW03t~;KUoIiQ`DnfyTpxFj1$Xo$&vI2O z8hbxu66UF`$c34;6(gdIw(GjAlf}uVW9H{`O`j!+*_SCCV$*lS*wStn>xE*{6%h>c znPDF-^g!071FQswC$rh?iNAs*ax1P{YH@BC(!cr*2vL*oQ) zaZG7%mX}tP9+%F3ild{W9K>lGb1v)*4@G>V^&H&!S=+AFj zzXFBD6l~nEP&X|`DkH%18L+nl#E!EQ>{;GAu|g*+XgnRPCCwtFeTmBzE?qfet$) zI@0~ar#;`@NAW%?oa0^Vk}vCSUk>Gc&dBHnm=%khHd} zYLUyvCfx_+@cB}E^uf~Cz-g`w`AV+j}NpsYq)jbO|7jW zwJUjwLg^GUE#-m0z|<9PxDRd8G3if>;{|j=6_&hN&gsAvEF&4x$NuJ z$L6%GCXz1g9NS*op;!eejryInF6fLJE;7(@Y}ULNyA9TD{4BK>pVs>Y`Nf6p*&VM} zdhC(vg(^fDU4QFyvKXpeI=Zkcv8#=zd9%;2T4_oUTd*qk13?Nuk~Peqvh{1$oZD;bhG&1n!BR7!AYHI>y0@Tlk6;H z-jEBmivZfj&FR{C@r>Z%k~1$vcISNTiitE^##kQKtENzss*QpFa{T{)7~P}i&Wqx{ z!%Q}Il#uwOW$x1M$mFvs#u;2|nM00IQf-lsSaZyjc>+m$u4)Bez3q{1M-f%xL;o(< zbVTb~_7}kOtpuV~K?F{H;K+!MUB@0Cmtz};_BTyNK9W(|D{Kon2C}EYRE}DF;fDN5 z0}O#_hs?taIjr zi%skL2|{iO1BwG6NpZuXXbhtRRsKd!aBW$fmdnwWGs5a<*Tc-X8zHU%d;Q+y7h7aZ zh`+`ULZyWO)WV=5K<+pG;?iz$VGz;OiQaru>~hZZP!UB-EUyyeG{%Td%v39J_$uU5 z?$7?gMjVNa^cyqXPPG0jgyEMr6mgc&Xf#;RVwy9=Y}=sf`1CMClO!S$_Y>MD_B#zv zE695tv!g*3>Mk>EkS2J6rcT1$t%3V8zh!_>1wuFy5DfnDIItvCi4^~>Ym=;I;1{ae zy{6Ql(Yn4>=bP&EO*O5wQ||KJ5)EGUeGm# zsn8`$f`Xno-6YY}+TUBQ9g=mLLn9Lt#uy7_4r$I5$FNK0udTwwT;WY2YOkVqmf+``(eNliQF=D3#>QhS%ljv1Pf=_R zA5w7Fh;~|I7VJVN=14jHD>~woNXVtf=2jPO+he{<2s_#@VtMOP2du19C@l{=kfC90 z&WkT&&a3e*``pt88^9mAUM(5{Q1>M>Md0`5+P&_u8J}RZsYvpUTy!+kt9qm+pMCEa4NZB&<9>=xV@( zCG`SV3(I1>y`RKH8@q@$LuCTuK6Xo8WciG7(8vSU%#87XC2KWnYsDl)v**ziqiDF7 z39|9#0^GkX21%!=zRvFy%;ELmuSQ{I z0#eJ^7L!+}kKpWl3m%`QBVBZiQ+nl6#8nI(UTH%o)QEcXeBE?!6rgbv`&kw?f$%mn zMVS9kB+2+le{f}*PqN$USb#5clsFmk>2m9hW4Ql(H!fg z3*An96>Ahe?Gn4S2V3_)X`Qv4^iHuzR{e#qdKY;hXZ~a){xTu8`y@zg(XH;UbM^(C!`;2WQy1}4_W5zk)r}i{MgqE^cngG(*pg~BB;=x$Y6px%3Q}AMI7PPnv zxVpKqbG~$YAGKnks}*L|)cEcYxsKdSNx5B=`J!yy~b zH;tSH3*!F%Rny2wEZN&EByEyiTf=G@f3!IS3%br?Gt9;{=bbJ;?S+dubX_=$OFdCn z`Jww>yciUW!p9&lC+WYn!vsBq$ys&o$hOlx`QkFx?;prZQL4N#qMqd*$?U4sXTi$Z^N(ljI*?X|4VqYoMW z%eC{p?p0bkl49-Fw<|_7MG;NEz^W$qZ*~oxKaELuqSbI!B*Ld^kO-0$K=?_zg--B$ z!r+vRAkZ|BXpM+$99gWzcztY2BF@@D71>pi4sN&7m z&gUX+Gu7(JNT2gUrYZ<%SlbPcEjhY|MmWiRP;Y8X!%{V}q#dN0|4>KINoIm@hZ7Mp zfAVtJOf)yWkk>9^-k+?r#gX z$M+|Ae!()`{e@exmrL$&9OTy_*u2I<7!%?+nbJ;7aBIx^PIZM%xt;38S{@8xXf`x5 z8r#Q4YPY!}Stpnx?d}>x!tiHGY8Bc}#cKiZTKb3UxzZ0F9kJy2U#tg$VgqX3>eG&R z3*9SuDW{mWD_c{^I*BUYR|7wGaa%(9zsk!>4(pdsV6GlS+A}H zkp%U8Y73y5Nc4hHO#J;`acY^`9#&fVrLRAuFB#!`9PPc6d1qy18Dia1aegC*Rz4?e?Uzn^mDjwa=lRJ?0?jzT$a`vTL8R&HNExtL@HQK znq%s841Z*hLI~;-n27|{(tW%2yU7r4s54X{D)J)|ZW3G5%1Ccc<)&j&46L?To1+gm zTCj6+MP2;ksi|&;g~g(3f1r*~oQy3bn{8mW;lW%Rk2Um$U@M$KwHtFeV3-En9HJhx zdx-SunC-c|1KhEER4mO)D&>vG(o(T7fD)L#K8Xf*LBTwcQnQ!HOsH_G3TmAvHdZUh z`^H`50LxtzjXL9oTYp=6-NNXY{3FGY0MzNafKW52qA5`@9(S$+3vusswe+ zggnOX80VD(>TtkMD&&D$rp;778l9>gM6d`a3W)I|Y74$USHbx!N>TG7H6(AS7(~tE4KGfZ_<4e?AQ=bsc8<`^@M@Yf};gCmN8(u{Gj2e z6jLsOiAq8wjAU%JH~wJAVaNj+fOgUWwh*;U=%1`8AC+X>S*oFz8UT zkqg74c(e4`?Ysy=1`;Z3Ej1^n`9(`Eq#5(HTwaX0O>z}1x5;+Mi9!zhHpe8ilw!2$ z9Q5{f;=ddgR5*?+4Mb9P2R~3ND}!HWJ#AWr8b`AVH;>H+|8P`pnxh{eTQ6^^r*%I^ z{^iJMZDBeQ!V{M=@Y`j)sP5u2PV2EX1c)Jt<1#(Uozm(YboCWkv8Y`>CKSwYxqQSH{^Qolp(P)=N)_+d3( zP!SWE0s2t`x1PK9xU`AbpK1soFQzkk;yu}T-^W^=n4pIuu=q!FI;@7;OCe~wegspZ z)hqBGw&{_(nWe;Avv|oKtNv(GWd6uNB3E4SH$&PAunx6%lwP~<_CQ6T(Rp>xS$0{l zPSBK8{diC7z#V4&#q38*F|tQs4|c=A1FGL0TVt;ju|`n6+s;!|N<{$X1K9wgIdBw& z{k{rk=X=MHrJ`B6Jl;BB`^2m4ld7qp+H}u#j9muk=8$2~`<{A-PR4&b=&-)L5aOxD zy70XJjoX~AMtKv}r(K!jV@zd_d-LaW*+Ng{w-9Dj$v9Nd$*AGH<(dC#6tmZT{qyh*Z^bmz|Ss4^u=XBf%1jeB!_(0W(lN+g2lSTAGcSWtnfs;$sb+Qr9nHx zGm8BIb&4wLkA;nhR930QcZ{{h!ISH-bN6ptPkSbTlzn?SU>)6$Gjz^ILGl@mif)s4 zmYu2XZ#Cw=pnNq<-atjUj8^}h*=&_LMNhyffXQDB)r)R6!tnJA=u)qPJw7J%6s+L9 z!U-`r4D`NTIheUoAb4*ZVT)G7_ew>2h6dF9FD)D&0)lLZe~TIh2t>at*Y@{?7aDt znGrKLK<4Lc%fse_L_$YZuEqDkUqXH5yLw|6RM&@Dh;Pf|xYOFcwe!4A$7CAC-jVOu zq0dvy16_iKz?Z1uKA)Is+5X^_E{4L?^H)Ancl4t&vI4=)cP^Du)PNq`aEx2KA-)k% zw9;XB%Npih%=afG;N@THYF>`e+!wRO`u~|N z;Hw0*$FmTH2un)R56SAhdK*3@w{pNRI_f}GUUhHi_5gK^L;By^X1v+zpm?X`zf8@Q zWXTKVx;={&!xBvknN9E7NcK*<_znoI461sA_EwUmRp}YFet|HCUJo357;=ogPFUpk zYW7O5v zy8duW!$4+^FsRTD?JAKM*yhoPGHVTla7&ntg32mk0M1hx1NC&tT{fDak5VSdTYD@I z4J|p0<)o!O#w#UsvCFKUaP`=_4fN=1U$p7vj6BXtY*_-jG|MGx-nwN^pL{CEgBMFdiD(8vXKO-Nh#MdlJWk60B0Lq(&Pfk&-^G^$fqgZ2SGH$4ks zXj9cNzJWD0qh!@8%pNu_rVI)XjdHo_%poW8NyzU)e`NMUsu}(a#v~gumKgG_;$|bH zPFMzMi`&ZmA(nqH8{W*51LHfOIsSK3@#iGXzyk!&y}>dD43Q%<8h%Lw`IpI6c1R!U z!~M*O-d!QDYd44%*Yp>Dt#Uk73xKiAb04>BSlO-rVkp!h9}SHXZ(chkG~CVn#yqeJ z;y|&TJYXdcDJyhIx3UuwuBZ|GD{xy+;+s}~=?S;we~0cFFA?BtSwZ17;VSsl9xmkG ze&3lH2HkdZBH&;1sEZ;UXu7Mbc-K_fWV$^#goT{(u9EYKkD~&_;Swp?_kJLU%cWKK z1H}6B%*dMLVton0Kos{%EqeI+&>IsM`R4CI5qBlK8K>q|yNIo!8-~t5_t#EKrRyz0 zd2oy4GOvz+v4$|PscvO|?EsSGjxViMW5)J(xYOqbgZSZY#KG`jTq5#mxXkSNvytK+ zF~R5jqvgjCXS5cIG}ZClCLPS=I7+w z?)?5QS^qMPyBad?`T z`QsTF&9w2>YHWh0CL<*2r2Gwo>=nHw(BeUkhqnxgCO=NoShy zvQdSQg~}XzZ$8kkFNE5@ zt$XU~ub%7G0ZrV{@R~u#-&weJtuWfymAmD%G@P2)1LVyE&Z?>n&7wisHB8-NQRgpS z+l$w%{JURgc#9fp+(W?IA}kGP4CW$8gNXHx-6gTqCl72SrS$jmg_v6dUx>pSBYSwC z17p%_o@VXc%W|dKI8`B0Sd zPp6wnmCf2_UT7%=mC-74F1-G2K8MaPYiI{<`<$l&!^Er)3sk29=P8M=6l)@)u)TAa zpQj$7uo$SOsWTDGVxm8J&Lr&zMGU#p0GJ!=5dAFXx0QrN0`*u@llv!E0|Mi#qPv@q zN-<*M5FGoX@O_7NU+hg8VX8srnX~~bn)(Dl`B z?Mdb;_ky9fZ0&cLI-%+FaR&8GF1SO?g3E(- z@=q!y)5Q#7ov?M*?xT*}*q-2P@wTM&lGvNsD*<8Jq4s-5)0PT(yWS)mdQ98_Md4o( zUUroMy>F!=0y+U6Nu?IgB((1@LeH0KV>C}3z$TBZs!GrKDWA%4Qla;?yQ)xuu@c@3 zciwVNrrZDVg8bBcI0rb-jq-g?e*su&-#RL>%21|UyP351n)NLNL_+(Fq~&w!E?A53 zwjV#qd{KCH5=`B*SjAWdrGyC=*<${Q!YY~9_@ws)1H6e({On)I;DlwYxM9X;AvPHh z;%d<2u=I|I-9t_t^(N|&ev?S4fGoI}^!y7Hf~+sLKY?9rAuDBQ z!da)1T~5rY5_0Vt=Vzl9(el%oqn!B3-$WA*e1YWs{Sv_TiSm^$(b*f|>fvB??P6rDvQY&uCpBnN*Dc<$d96fVeAK(i ztp}1UTk==n>Gm(LKi=KUC#j}yjT-S{hxr0BZrQvo(epcZL z%~@z?A=LVsj(sKVD}IAtJG|^QYwcix1Lh2M;OOdPlw?q{h#<-YbG`E z|Nbmt!fmtJ4U1U;bmRGJV5PKgzKxl z6PBB>Ll+O^Hhp$}p&vmSQ*9@UC$gOF^n-cuAU+0SALmIC2^QxgS$@}ENq5O5Ft6=N zyr`E)j-Nele$v^yA8Lp|$s-M0@?CLcH+&x8((&K%z08Y3ziqDW z7m(b?IM(c!G_BZw=5X@`>Ufb0UAv*{Uf%t08odq^exJjK(?mNl=_+c|x^vb&HO6SU z&s&I5mggYtwvJWygZ07&B7r2<2xpP7k`c1e}Ta?a@HKgS3jcJ%9cj>yZ86 zsJiY1X$QVSkw^itDipkLGqcoiMzyTU4{EK3wyxanD^#TCM(WSEkQZ;D6OUH`Br6#{ z;SSH%AKqc9DsBgzXNubKsw3(0#ySAIYE;nz?6S-yibSJ+BR}dMR`Y?~8o#38xz8EX zc>()fJ6ek^l68}$>2yf0^D(a4$ZDg#42Vt`E0QaX_H*wm-?sw7lYbu_m&>KTYu3aT z&LbXrie3C`jNJIK8rN;R?OUGOE22x%8g)f$g`cILus#>#S>k!2`VwM5+Yh=p=`>^x zK8{Qjz+qrVpeEF}4YE-=HnM|u86BBZVW_OgVG8R%?b!Y8$dXdJ?+^wC*V=HSBh=k@Lv zA9I%C{G}E?wv65C?($8WtBn?~q;?oPp{I`JE*{GUIPpu0Kg1kE$kof<+>A+`{y) z1`wlAkq7=$RT>8x3yM-8x8oy{*;VhZ#A|qF3Cm#=H}I zMAcdbmq_#^bv%1<3H|oyW6D%zT#OC;p=8`{9trVc#5E3e-V5LPe2v17gt7p$*4_iH zWs9=jRh{1OH79u)m6N@w|DC_#$+DIbyUm-f1RXO?Ga3xY?m9)VwP+}`DX7=evtDZ(2+5V zNKZ0?rC8@hSiVP6a){M775P!KhSLp^N3`yc+~|26jySi6xM%B3-Ss6a4J$HfL$4*p z2X?@cuEWGQ#5JQ|_A{OUgzUrT_dlP_rpf*;I>%qMh{%c?konKb$w^mN-U!``gtl5# z0Et+k`wtur;D5N;jqyiwcNnL>E)M7Efjt1Dzz@gNR+hxoyK1`Z!z{cNmfNlSNX<9G z$1Qn(fFD(XX-n!>?7>=fe4#2+(bS-BUB499OaIts{V_cb9k8ZCOitE=Sd+P(GS2IW z?_?P7zRYTeiC$L*AaskZHhsXJw8vQS1tM3=UWl%LWBj#oeS(rg`Ta>AUEM8u4aBSj zLu!d5K7JQ5PsTxt%gF#@MqR(@TQ3N9p{4&2z6yP$f}!*;&pPR1wWiLDmie$HJ!`Px zhrT>i^92$hCAVj)u9{EYLP1Q@NXl3O`iUVazxd}Qetb~`^W{5X@b!aYuWl1C>6-KOAh;)BmFIozbvv+>U*-5#LiDAs&SC_G|LoHQswMY6> z2NhldYb|vAMO6OnFG~{1==XQ(07To3d5Am`Yy?{`x8+!`dQd5~|3ZAXe_rR%HrEdG zycEJhs`fFFIvn*Bo5sAI3x^BTdkjEOFYnR|S6m7YkM4fR9JD!@CM7EAuX%&{8kQKX zZ|Och8inr_{C6n*i$5wyaQpg^OUpY`p_%EF3WYIAHzjY#lX142TCzmRC=3&)B!V-` zPt9&V8LjF$7SOI{%J;Oq7A69T(0z7J&eNGzbg{%r>!0=Am`6sgC4%X{HcTRu0kkyz zP;IrYf&ojhu}!4>m@)qtJB%`x&v>P{w=fTBwv&$h$^-!lqz&XO*>0S;`tG`~TUe!# zS;%r7&h?2XiT9!dOFt)TpQLUCL&9~N;|Ph-y=~WM?&~p7^OaeB{&~I~+V+?!5svzX zr#$GlL!(qW>2R2S@@1X7=-r6^(dY>*&CDupUkxrj4CW9`1`Sh?0My}JX zC;+sy^_9M7m)4&0!{Vp5Q&tJQiDpm1W>@NfmyT*1wIg(d$IeAQDFC?nQU3~X7t_^x z?!5hyT*cbQjw;f)Zc`K6;b~`w{TDl;T}TIS|6SL*`oQUiL(<=mW@wMad4jUnF}zDI zI6Hjt3iwnzeAV3wL^JGnKd!@!5T-pEliSkN;vhiqeTRsa5KqmIw_NTrN`dFISA0@Y z<%USiJ6O`+woxrKlWR3P?6{!R%>lCTu&nC-Sj?@Rdrp#TD}S?y)H?n~ZusEYgdeQ? zbXj$wEpsif*5eQEM22ot4DCx&E8R4p9V$cF_HMxXwAIc&{vX?cMCdG_i*J;hqBcow zs!gk~^lp%$=Tk~U(!*<(_WD@M3ezK2Iw6l&vEZ{3-eGwI4BYWWvL-WxA*lNi7X8&V zfrT1>R;7vMI~#;&3U0#NF9vD!8|oJ~j1TB0t! zar#mJ^cVCv7Q3t+{5;+g{m1EuJ5gszsY625)kpi4ShJ6{1;XeUn;#T03DR>JI6{`! zF7@$R^FNM0Z0$&3AIl*HcGFq;-jc~Tqw6yx&Ir;G*5+48c@pMCv=z-e@>uWZtQ|<) zpL+c}hnb!D!J4J9A%dmewvho!N4|3ext&(oS>@w}Ajngwy(A(D#n^Vkm3#xRTkf39 zYCh|BB_Fije+_bK8wLJ|CReT+kNYq%UXg}dNJ}m={P!D2PJfI)i&&-$AKE_q^pA7q z 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 - - - - - Finale for Mac - 2016-09-12 - - - - - - - - - - 7.2319 - 40 - - - 1545 - 1194 - - 70 - 70 - 88 - 88 - - - - - 0 - 0 - - 121 - 70 - - - 0.7487 - 5 - 0.7487 - 0.7487 - 5 - 0.7487 - 0.7487 - 0.7487 - 0.7487 - 0.7487 - 60 - 60 - 120 - 8 - - - - - - Score - - - - MusicXML Part - - SmartMusic SoftSynth 1 - - - 1 - 15489 - 1 - 80 - 0 - - - - - - - - - - 70 - 0 - - 211 - - system - - - 2 - - 0 - major - - - - G - 2 - - - - - - F - 5 - - 2 - 1 - quarter - down - - - - B - 4 - - 2 - 2 - quarter - down - - - 2 - - - - F - 4 - - 2 - 2 - quarter - up - - - - C - 5 - - 2 - 4 - quarter - down - - - light-heavy - - - - - diff --git a/docs/DevNotes/MusicXML Standard Sounds.xml b/docs/DevNotes/MusicXML Standard Sounds.xml deleted file mode 100644 index 016d9a914..000000000 --- a/docs/DevNotes/MusicXML Standard Sounds.xml +++ /dev/null @@ -1,888 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/DevNotes/MusicXMLSounds.xml b/docs/DevNotes/MusicXMLSounds.xml deleted file mode 100644 index 93871d279..000000000 --- a/docs/DevNotes/MusicXMLSounds.xml +++ /dev/null @@ -1,888 +0,0 @@ - - brass.alphorn - brass.alto-horn - brass.baritone-horn - brass.bugle - brass.bugle.alto - brass.bugle.baritone - brass.bugle.contrabass - brass.bugle.euphonium-bugle - brass.bugle.mellophone-bugle - brass.bugle.soprano - brass.cimbasso - brass.conch-shell - brass.cornet - brass.cornet.soprano - brass.cornett - brass.cornett.tenor - brass.cornettino - brass.didgeridoo - brass.euphonium - brass.fiscorn - brass.flugelhorn - brass.french-horn - brass.group - brass.group.synth - brass.helicon - brass.horagai - brass.kuhlohorn - brass.mellophone - brass.natural-horn - brass.ophicleide - brass.posthorn - brass.rag-dung - brass.sackbutt - brass.sackbutt.alto - brass.sackbutt.bass - brass.sackbutt.tenor - brass.saxhorn - brass.serpent - brass.shofar - brass.sousaphone - brass.trombone - brass.trombone.alto - brass.trombone.bass - brass.trombone.contrabass - brass.trombone.tenor - brass.trumpet - brass.trumpet.baroque - brass.trumpet.bass - brass.trumpet.bflat - brass.trumpet.c - brass.trumpet.d - brass.trumpet.piccolo - brass.trumpet.pocket - brass.trumpet.slide - brass.trumpet.tenor - brass.tuba - brass.tuba.bass - brass.tuba.subcontrabass - brass.vienna-horn - brass.vuvuzela - brass.wagner-tuba - drum.apentemma - drum.ashiko - drum.atabaque - drum.atoke - drum.atsimevu - drum.axatse - drum.bass-drum - drum.bata - drum.bata.itotele - drum.bata.iya - drum.bata.okonkolo - drum.bendir - drum.bodhran - drum.bombo - drum.bongo - drum.bougarabou - drum.buffalo-drum - drum.cajon - drum.chenda - drum.chu-daiko - drum.conga - drum.cuica - drum.dabakan - drum.daff - drum.dafli - drum.daibyosi - drum.damroo - drum.darabuka - drum.def - drum.dhol - drum.dholak - drum.djembe - drum.doira - drum.dondo - drum.doun-doun-ba - drum.duff - drum.dumbek - drum.fontomfrom - drum.frame-drum - drum.frame-drum.arabian - drum.geduk - drum.ghatam - drum.gome - drum.group - drum.group.chinese - drum.group.ewe - drum.group.indian - drum.group.set - drum.hand-drum - drum.hira-daiko - drum.ibo - drum.igihumurizo - drum.inyahura - drum.ishakwe - drum.jang-gu - drum.kagan - drum.kakko - drum.kanjira - drum.kendhang - drum.kendhang.ageng - drum.kendhang.ciblon - drum.kenkeni - drum.khol - drum.kick-drum - drum.kidi - drum.ko-daiko - drum.kpanlogo - drum.kudum - drum.lambeg - drum.lion-drum - drum.log-drum - drum.log-drum.african - drum.log-drum.native - drum.log-drum.nigerian - drum.madal - drum.maddale - drum.mridangam - drum.naal - drum.nagado-daiko - drum.nagara - drum.naqara - drum.o-daiko - drum.okawa - drum.okedo-daiko - drum.pahu-hula - drum.pakhawaj - drum.pandeiro - drum.pandero - drum.powwow - drum.pueblo - drum.repinique - drum.riq - drum.rototom - drum.sabar - drum.sakara - drum.sampho - drum.sangban - drum.shime-daiko - drum.slit-drum - drum.slit-drum.krin - drum.snare-drum - drum.snare-drum.electric - drum.sogo - drum.surdo - drum.tabla - drum.tabla.bayan - drum.tabla.dayan - drum.taiko - drum.talking - drum.tama - drum.tamborita - drum.tambourine - drum.tamte - drum.tangku - drum.tan-tan - drum.taphon - drum.tar - drum.tasha - drum.tenor-drum - drum.teponaxtli - drum.thavil - drum.the-box - drum.timbale - drum.timpani - drum.tinaja - drum.toere - drum.tombak - drum.tom-tom - drum.tom-tom.synth - drum.tsuzumi - drum.tumbak - drum.uchiwa-daiko - drum.udaku - drum.udu - drum.zarb - effect.aeolian-harp - effect.air-horn - effect.applause - effect.bass-string-slap - effect.bird - effect.bird.nightingale - effect.bird.tweet - effect.breath - effect.bubble - effect.bullroarer - effect.burst - effect.car - effect.car.crash - effect.car.engine - effect.car.pass - effect.car.stop - effect.crickets - effect.dog - effect.door.creak - effect.door.slam - effect.explosion - effect.flute-key-click - effect.footsteps - effect.frogs - effect.guitar-cutting - effect.guitar-fret - effect.gunshot - effect.hand-clap - effect.heartbeat - effect.helicopter - effect.high-q - effect.horse-gallop - effect.jet-plane - effect.laser-gun - effect.laugh - effect.lions-roar - effect.machine-gun - effect.marching-machine - effect.metronome-bell - effect.metronome-click - effect.pat - effect.punch - effect.rain - effect.scratch - effect.scream - effect.seashore - effect.siren - effect.slap - effect.snap - effect.stamp - effect.starship - effect.stream - effect.telephone-ring - effect.thunder - effect.train - effect.trash-can - effect.whip - effect.whistle - effect.whistle.mouth-siren - effect.whistle.police - effect.whistle.slide - effect.whistle.train - effect.wind - keyboard.accordion - keyboard.bandoneon - keyboard.celesta - keyboard.clavichord - keyboard.clavichord.synth - keyboard.concertina - keyboard.fortepiano - keyboard.harmonium - keyboard.harpsichord - keyboard.ondes-martenot - keyboard.organ - keyboard.organ.drawbar - keyboard.organ.percussive - keyboard.organ.pipe - keyboard.organ.reed - keyboard.organ.rotary - keyboard.piano - keyboard.piano.electric - keyboard.piano.grand - keyboard.piano.honky-tonk - keyboard.piano.prepared - keyboard.piano.toy - keyboard.piano.upright - keyboard.virginal - metal.adodo - metal.anvil - metal.babendil - metal.bells.agogo - metal.bells.almglocken - metal.bells.bell-plate - metal.bells.bell-tree - metal.bells.carillon - metal.bells.chimes - metal.bells.chimta - metal.bells.chippli - metal.bells.church - metal.bells.cowbell - metal.bells.dawuro - metal.bells.gankokwe - metal.bells.ghungroo - metal.bells.hatheli - metal.bells.jingle-bell - metal.bells.khartal - metal.bells.mark-tree - metal.bells.sistrum - metal.bells.sleigh-bells - metal.bells.temple - metal.bells.tibetan - metal.bells.tinklebell - metal.bells.trychel - metal.bells.wind-chimes - metal.bells.zills - metal.berimbau - metal.brake-drums - metal.crotales - metal.cymbal.bo - metal.cymbal.ceng-ceng - metal.cymbal.chabara - metal.cymbal.chinese - metal.cymbal.ching - metal.cymbal.clash - metal.cymbal.crash - metal.cymbal.finger - metal.cymbal.hand - metal.cymbal.kesi - metal.cymbal.manjeera - metal.cymbal.reverse - metal.cymbal.ride - metal.cymbal.sizzle - metal.cymbal.splash - metal.cymbal.suspended - metal.cymbal.tebyoshi - metal.cymbal.tibetan - metal.cymbal.tingsha - metal.flexatone - metal.gong - metal.gong.ageng - metal.gong.agung - metal.gong.chanchiki - metal.gong.chinese - metal.gong.gandingan - metal.gong.kempul - metal.gong.kempyang - metal.gong.ketuk - metal.gong.kkwenggwari - metal.gong.luo - metal.gong.singing - metal.gong.thai - metal.guira - metal.hang - metal.hi-hat - metal.jaw-harp - metal.kengong - metal.murchang - metal.musical-saw - metal.singing-bowl - metal.spoons - metal.steel-drums - metal.tamtam - metal.thundersheet - metal.triangle - metal.washboard - pitched-percussion.angklung - pitched-percussion.balafon - pitched-percussion.bell-lyre - pitched-percussion.bells - pitched-percussion.bianqing - pitched-percussion.bianzhong - pitched-percussion.bonang - pitched-percussion.cimbalom - pitched-percussion.crystal-glasses - pitched-percussion.dan-tam-thap-luc - pitched-percussion.fangxiang - pitched-percussion.gandingan-a-kayo - pitched-percussion.gangsa - pitched-percussion.gender - pitched-percussion.giying - pitched-percussion.glass-harmonica - pitched-percussion.glockenspiel - pitched-percussion.glockenspiel.alto - pitched-percussion.glockenspiel.soprano - pitched-percussion.gyil - pitched-percussion.hammer-dulcimer - pitched-percussion.handbells - pitched-percussion.kalimba - pitched-percussion.kantil - pitched-percussion.khim - pitched-percussion.kulintang - pitched-percussion.kulintang-a-kayo - pitched-percussion.kulintang-a-tiniok - pitched-percussion.likembe - pitched-percussion.luntang - pitched-percussion.marimba - pitched-percussion.marimba.bass - pitched-percussion.mbira - pitched-percussion.mbira.array - pitched-percussion.metallophone - pitched-percussion.metallophone.alto - pitched-percussion.metallophone.bass - pitched-percussion.metallophone.soprano - pitched-percussion.music-box - pitched-percussion.pelog-panerus - pitched-percussion.pemade - pitched-percussion.penyacah - pitched-percussion.ranat.ek - pitched-percussion.ranat.ek-lek - pitched-percussion.ranat.thum - pitched-percussion.ranat.thum-lek - pitched-percussion.reyong - pitched-percussion.sanza - pitched-percussion.saron-barung - pitched-percussion.saron-demong - pitched-percussion.saron-panerus - pitched-percussion.slendro-panerus - pitched-percussion.slentem - pitched-percussion.tsymbaly - pitched-percussion.tubes - pitched-percussion.tubular-bells - pitched-percussion.vibraphone - pitched-percussion.xylophone - pitched-percussion.xylophone.alto - pitched-percussion.xylophone.bass - pitched-percussion.xylophone.soprano - pitched-percussion.xylorimba - pitched-percussion.yangqin - pluck.archlute - pluck.autoharp - pluck.baglama - pluck.bajo - pluck.balalaika - pluck.balalaika.alto - pluck.balalaika.bass - pluck.balalaika.contrabass - pluck.balalaika.piccolo - pluck.balalaika.prima - pluck.balalaika.secunda - pluck.bandola - pluck.bandura - pluck.bandurria - pluck.banjo - pluck.banjo.tenor - pluck.banjolele - pluck.barbat - pluck.bass - pluck.bass.acoustic - pluck.bass.bolon - pluck.bass.electric - pluck.bass.fretless - pluck.bass.guitarron - pluck.bass.synth - pluck.bass.synth.lead - pluck.bass.washtub - pluck.bass.whamola - pluck.begena - pluck.biwa - pluck.bordonua - pluck.bouzouki - pluck.bouzouki.irish - pluck.celtic-harp - pluck.charango - pluck.chitarra-battente - pluck.cithara - pluck.cittern - pluck.cuatro - pluck.dan-bau - pluck.dan-nguyet - pluck.dan-tranh - pluck.dan-ty-ba - pluck.diddley-bow - pluck.domra - pluck.domu - pluck.dulcimer - pluck.dutar - pluck.duxianqin - pluck.ektara - pluck.geomungo - pluck.gottuvadhyam - pluck.guitar - pluck.guitar.acoustic - pluck.guitar.electric - pluck.guitar.nylon-string - pluck.guitar.pedal-steel - pluck.guitar.portuguese - pluck.guitar.requinto - pluck.guitar.resonator - pluck.guitar.steel-string - pluck.guitjo - pluck.guitjo.double-neck - pluck.guqin - pluck.guzheng - pluck.guzheng.choazhou - pluck.harp - pluck.harp-guitar - pluck.huapanguera - pluck.jarana-huasteca - pluck.jarana-jarocha - pluck.jarana-jarocha.mosquito - pluck.jarana-jarocha.primera - pluck.jarana-jarocha.segunda - pluck.jarana-jarocha.tercera - pluck.kabosy - pluck.kantele - pluck.kanun - pluck.kayagum - pluck.kobza - pluck.komuz - pluck.kora - pluck.koto - pluck.kutiyapi - pluck.langeleik - pluck.laud - pluck.lute - pluck.lyre - pluck.mandobass - pluck.mandocello - pluck.mandola - pluck.mandolin - pluck.mandolin.octave - pluck.mandora - pluck.mandore - pluck.marovany - pluck.musical-bow - pluck.ngoni - pluck.oud - pluck.pipa - pluck.psaltery - pluck.ruan - pluck.sallaneh - pluck.sanshin - pluck.santoor - pluck.sanxian - pluck.sarod - pluck.saung - pluck.saz - pluck.se - pluck.setar - pluck.shamisen - pluck.sitar - pluck.synth - pluck.synth.charang - pluck.synth.chiff - pluck.synth.stick - pluck.tambura - pluck.tambura.bulgarian - pluck.tambura.female - pluck.tambura.male - pluck.tar - pluck.theorbo - pluck.timple - pluck.tiple - pluck.tres - pluck.ukulele - pluck.ukulele.tenor - pluck.valiha - pluck.veena - pluck.veena.mohan - pluck.veena.rudra - pluck.veena.vichitra - pluck.vihuela - pluck.vihuela.mexican - pluck.xalam - pluck.yueqin - pluck.zither - pluck.zither.overtone - rattle.afoxe - rattle.birds - rattle.cabasa - rattle.caxixi - rattle.cog - rattle.ganza - rattle.hosho - rattle.jawbone - rattle.kayamba - rattle.kpoko-kpoko - rattle.lava-stones - rattle.maraca - rattle.rain-stick - rattle.ratchet - rattle.rattle - rattle.shaker - rattle.shaker.egg - rattle.shekere - rattle.sistre - rattle.televi - rattle.vibraslap - rattle.wasembe - strings.ajaeng - strings.arpeggione - strings.baryton - strings.cello - strings.cello.piccolo - strings.contrabass - strings.crwth - strings.dan-gao - strings.dihu - strings.erhu - strings.erxian - strings.esraj - strings.fiddle - strings.fiddle.hardanger - strings.gadulka - strings.gaohu - strings.gehu - strings.group - strings.group.synth - strings.haegeum - strings.hurdy-gurdy - strings.igil - strings.kamancha - strings.kokyu - strings.laruan - strings.leiqin - strings.lirone - strings.lyra.byzantine - strings.lyra.cretan - strings.morin-khuur - strings.nyckelharpa - strings.octobass - strings.rebab - strings.rebec - strings.sarangi - strings.stroh-violin - strings.tromba-marina - strings.vielle - strings.viol - strings.viol.alto - strings.viol.bass - strings.viol.tenor - strings.viol.treble - strings.viol.violone - strings.viola - strings.viola-damore - strings.violin - strings.violono.piccolo - strings.violotta - strings.yayli-tanbur - strings.yazheng - strings.zhonghu - synth.effects - synth.effects.atmosphere - synth.effects.brightness - synth.effects.crystal - synth.effects.echoes - synth.effects.goblins - synth.effects.rain - synth.effects.sci-fi - synth.effects.soundtrack - synth.group - synth.group.fifths - synth.group.orchestra - synth.pad - synth.pad.bowed - synth.pad.choir - synth.pad.halo - synth.pad.metallic - synth.pad.polysynth - synth.pad.sweep - synth.pad.warm - synth.theremin - synth.tone.sawtooth - synth.tone.sine - synth.tone.square - voice.aa - voice.alto - voice.aw - voice.baritone - voice.bass - voice.child - voice.countertenor - voice.doo - voice.ee - voice.female - voice.kazoo - voice.male - voice.mezzo-soprano - voice.mm - voice.oo - voice.percussion - voice.percussion.beatbox - voice.soprano - voice.synth - voice.talk-box - voice.tenor - voice.vocals - wind.flutes.bansuri - wind.flutes.blown-bottle - wind.flutes.calliope - wind.flutes.danso - wind.flutes.di-zi - wind.flutes.dvojnice - wind.flutes.fife - wind.flutes.flageolet - wind.flutes.flute - wind.flutes.flute.alto - wind.flutes.flute.bass - wind.flutes.flute.contra-alto - wind.flutes.flute.contrabass - wind.flutes.flute.double-contrabass - wind.flutes.flute.irish - wind.flutes.flute.piccolo - wind.flutes.flute.subcontrabass - wind.flutes.fujara - wind.flutes.gemshorn - wind.flutes.hocchiku - wind.flutes.hun - wind.flutes.kaval - wind.flutes.kawala - wind.flutes.khlui - wind.flutes.knotweed - wind.flutes.koncovka.alto - wind.flutes.koudi - wind.flutes.ney - wind.flutes.nohkan - wind.flutes.nose - wind.flutes.ocarina - wind.flutes.overtone.tenor - wind.flutes.palendag - wind.flutes.panpipes - wind.flutes.quena - wind.flutes.recorder - wind.flutes.recorder.alto - wind.flutes.recorder.bass - wind.flutes.recorder.contrabass - wind.flutes.recorder.descant - wind.flutes.recorder.garklein - wind.flutes.recorder.great-bass - wind.flutes.recorder.sopranino - wind.flutes.recorder.soprano - wind.flutes.recorder.tenor - wind.flutes.ryuteki - wind.flutes.shakuhachi - wind.flutes.shepherds-pipe - wind.flutes.shinobue - wind.flutes.shvi - wind.flutes.suling - wind.flutes.tarka - wind.flutes.tumpong - wind.flutes.venu - wind.flutes.whistle - wind.flutes.whistle.alto - wind.flutes.whistle.low-irish - wind.flutes.whistle.shiva - wind.flutes.whistle.slide - wind.flutes.whistle.tin - wind.flutes.whistle.tin.bflat - wind.flutes.whistle.tin.d - wind.flutes.xiao - wind.flutes.xun - wind.group - wind.jug - wind.pipes.bagpipes - wind.pipes.gaida - wind.pipes.highland - wind.pipes.uilleann - wind.pungi - wind.reed.albogue - wind.reed.alboka - wind.reed.algaita - wind.reed.arghul - wind.reed.basset-horn - wind.reed.bassoon - wind.reed.bawu - wind.reed.bifora - wind.reed.bombarde - wind.reed.chalumeau - wind.reed.clarinet - wind.reed.clarinet.a - wind.reed.clarinet.alto - wind.reed.clarinet.bass - wind.reed.clarinet.basset - wind.reed.clarinet.bflat - wind.reed.clarinet.contra-alto - wind.reed.clarinet.contrabass - wind.reed.clarinet.eflat - wind.reed.clarinet.piccolo.aflat - wind.reed.clarinette-damour - wind.reed.contrabass - wind.reed.contrabassoon - wind.reed.cornamuse - wind.reed.cromorne - wind.reed.crumhorn - wind.reed.crumhorn.alto - wind.reed.crumhorn.bass - wind.reed.crumhorn.great-bass - wind.reed.crumhorn.soprano - wind.reed.crumhorn.tenor - wind.reed.diple - wind.reed.diplica - wind.reed.duduk - wind.reed.dulcian - wind.reed.dulzaina - wind.reed.english-horn - wind.reed.guanzi - wind.reed.harmonica - wind.reed.harmonica.bass - wind.reed.heckel-clarina - wind.reed.heckelphone - wind.reed.heckelphone.piccolo - wind.reed.heckelphone-clarinet - wind.reed.hichiriki - wind.reed.hirtenschalmei - wind.reed.hne - wind.reed.hornpipe - wind.reed.houguan - wind.reed.hulusi - wind.reed.jogi-baja - wind.reed.ken-bau - wind.reed.khaen-mouth-organ - wind.reed.launeddas - wind.reed.maqrunah - wind.reed.melodica - wind.reed.mijwiz - wind.reed.mizmar - wind.reed.nadaswaram - wind.reed.oboe - wind.reed.oboe.bass - wind.reed.oboe.piccolo - wind.reed.oboe-da-caccia - wind.reed.oboe-damore - wind.reed.octavin - wind.reed.pi - wind.reed.pibgorn - wind.reed.piri - wind.reed.rackett - wind.reed.rauschpfeife - wind.reed.rhaita - wind.reed.rothphone - wind.reed.sarrusaphone - wind.reed.saxonette - wind.reed.saxophone - wind.reed.saxophone.alto - wind.reed.saxophone.aulochrome - wind.reed.saxophone.baritone - wind.reed.saxophone.bass - wind.reed.saxophone.contrabass - wind.reed.saxophone.melody - wind.reed.saxophone.mezzo-soprano - wind.reed.saxophone.sopranino - wind.reed.saxophone.sopranissimo - wind.reed.saxophone.soprano - wind.reed.saxophone.subcontrabass - wind.reed.saxophone.tenor - wind.reed.shawm - wind.reed.shenai - wind.reed.sheng - wind.reed.sipsi - wind.reed.sopila - wind.reed.sorna - wind.reed.sralai - wind.reed.suona - wind.reed.surnai - wind.reed.taepyeongso - wind.reed.tarogato - wind.reed.tarogato.ancient - wind.reed.trompeta-china - wind.reed.tubax - wind.reed.xaphoon - wind.reed.zhaleika - wind.reed.zurla - wind.reed.zurna - wood.agogo-block - wood.agung-a-tamlang - wood.ahoko - wood.bones - wood.castanets - wood.claves - wood.drum-sticks - wood.gourd - wood.granite-block - wood.guban - wood.guiro - wood.hyoushigi - wood.ipu - wood.jam-block - wood.kaekeeke - wood.kagul - wood.kalaau - wood.kashiklar - wood.kubing - wood.pan-clappers - wood.sand-block - wood.slapstick - wood.stir-drum - wood.temple-block - wood.tic-toc-block - wood.tonetang - wood.wood-block - \ No newline at end of file diff --git a/docs/DevNotes/PerformanceNotes.txt b/docs/DevNotes/PerformanceNotes.txt deleted file mode 100644 index 966b276ac..000000000 --- a/docs/DevNotes/PerformanceNotes.txt +++ /dev/null @@ -1,40 +0,0 @@ -Baseline --------------------------------------------------------------------- - -274 tests, 0 failures, 0 errors -Total runtime for all tests 18.2356 sec -Program ended with exit code: 0 - -274 tests, 0 failures, 0 errors -Total runtime for all tests 17.4334 sec -Program ended with exit code: 0 - -274 tests, 0 failures, 0 errors -Total runtime for all tests 17.2236 sec -Program ended with exit code: 0 - - -After Optimizing Note --------------------------------------------------------------------- - -274 tests, 0 failures, 0 errors -Total runtime for all tests 14.7685 sec -Program ended with exit code: 0 - -274 tests, 0 failures, 0 errors -Total runtime for all tests 14.6552 sec -Program ended with exit code: 0 - -274 tests, 0 failures, 0 errors -Total runtime for all tests 14.6044 sec -Program ended with exit code: 0 - ---without mutex -274 tests, 0 failures, 0 errors -Total runtime for all tests 14.9611 sec -Program ended with exit code: 0 - - ----- -DirectionType -Direction -FullNoteTypeChoice -Key \ No newline at end of file diff --git a/docs/DevNotes/StaffExperiment.xml b/docs/DevNotes/StaffExperiment.xml deleted file mode 100644 index 5930e0fcf..000000000 --- a/docs/DevNotes/StaffExperiment.xml +++ /dev/null @@ -1,155 +0,0 @@ - - - - - - Finale for Mac - 2016-09-12 - - - - - - - - - - 7.2319 - 40 - - - 1545 - 1194 - - 70 - 70 - 88 - 88 - - - - - 0 - 0 - - 121 - 70 - - - 0.7487 - 5 - 0.7487 - 0.7487 - 5 - 0.7487 - 0.7487 - 0.7487 - 0.7487 - 0.7487 - 60 - 60 - 120 - 8 - - - - - - Score - - - - MusicXML Part - - SmartMusic SoftSynth 1 - - - 1 - 15489 - 1 - 80 - 0 - - - - - - - - - - 70 - 0 - - 211 - - system - - - 2 - - 0 - major - - - 2 - - G - 2 - - - - - - F - 5 - - 2 - 1 - quarter - down - 1 - - - - B - 4 - - 2 - 1 - quarter - down - 2 - - - - F - 4 - - 2 - 1 - quarter - up - - - - - C - 5 - - 2 - 1 - quarter - down - - - - light-heavy - - - - - diff --git a/docs/DevNotes/TupletsTest.musx b/docs/DevNotes/TupletsTest.musx deleted file mode 100644 index b1cb1cdd7e207325ff550889cbda240c3f767f94..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 89451 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

U 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®uMEkLN1l3@(|r;f?Q0#2`ZcF_Y)}8 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 - - - Tuptlets Test - - - Finale for Mac - 2016-09-15 - - - - - - - - - - 7.2319 - 40 - - - 1545 - 1194 - - 140 - 70 - 70 - 70 - - - - - 0 - 0 - - 121 - 70 - - - 0.7487 - 5 - 0.7487 - 0.7487 - 5 - 0.7487 - 0.7487 - 0.7487 - 0.7487 - 0.7487 - 60 - 60 - 120 - 8 - - - - - - title - Tuptlets Test - - - - Flute - Fl. - - ARIA Player - wind.flutes.flute - - Garritan Instruments for Finale - 001. Woodwinds/1. Flutes/Flute Plr1 - - - Bank 1 - - 1 - 1 - 80 - 0 - - - - - - - - - 177 - - system - - - 60 - - 0 - major - - - - G - 2 - - - - - - F - 5 - - 20 - 1 - eighth - - 3 - 2 - - down - begin - - - - - - - G - 5 - - 20 - 1 - eighth - - 3 - 2 - - down - continue - - - - A - 5 - - 20 - 1 - eighth - - 3 - 2 - - down - end - - - - - - - F - 5 - - 40 - 1 - quarter - - 3 - 2 - eighth - - down - - - - - - - G - 5 - - 20 - 1 - eighth - - 3 - 2 - eighth - - down - - - - - - - F - 5 - - 20 - 1 - eighth - - 3 - 2 - - down - - - - - - - G - 5 - - 40 - 1 - quarter - - 3 - 2 - - down - - - - - - - A - 5 - - 20 - 1 - eighth - - 3 - 2 - - down - begin - - - - - - - G - 5 - - 20 - 1 - eighth - - 3 - 2 - - down - continue - - - - F - 5 - - 20 - 1 - eighth - - 3 - 2 - - down - end - - - - - - - - - - 20 - 1 - eighth - - 3 - 2 - - - - - - - - G - 5 - - 20 - 1 - eighth - - 3 - 2 - - down - begin - - - - A - 5 - - 20 - 1 - eighth - - 3 - 2 - - down - end - - - - - - - 40 - 1 - quarter - - 3 - 2 - eighth - - - - - - - - A - 5 - - 20 - 1 - eighth - - 3 - 2 - eighth - - down - - - - - - - 20 - 1 - eighth - - 3 - 2 - - - - - - - - A - 5 - - 40 - 1 - quarter - - 3 - 2 - - down - - - - - - - A - 5 - - 20 - 1 - eighth - - 3 - 2 - - down - begin - - - - - - - 20 - 1 - eighth - - 3 - 2 - - - - - F - 5 - - 20 - 1 - eighth - - 3 - 2 - - down - end - - - - - - - - - - 114 - - - - - 20 - 1 - eighth - - 3 - 2 - - - - - - - - G - 5 - - 20 - 1 - eighth - - 3 - 2 - - down - - - - 20 - 1 - eighth - - 3 - 2 - - - - - - - - C - 6 - - 12 - 1 - 16th - - 5 - 4 - - down - begin - begin - - - - - - - B - 5 - - 12 - 1 - 16th - - 5 - 4 - - down - continue - continue - - - - A - 5 - - 12 - 1 - 16th - - 5 - 4 - - down - continue - continue - - - - G - 5 - - 12 - 1 - 16th - - 5 - 4 - - down - continue - continue - - - - F - 5 - - 12 - 1 - 16th - - 5 - 4 - - down - end - end - - - - - - - F - 5 - - 48 - 1 - quarter - - 5 - 4 - 16th - - down - - - - - - - A - 5 - - 12 - 1 - 16th - - 5 - 4 - 16th - - down - - - - - - - G - 5 - - 12 - 1 - 16th - - 5 - 4 - - down - - - - - - - F - 5 - - 48 - 1 - quarter - - 5 - 4 - - down - - - - - - - - - - F - 5 - - 12 - 1 - 16th - - 5 - 4 - - down - begin - forward hook - - - - - - - 12 - 1 - 16th - - 5 - 4 - - - - - A - 5 - - 24 - 1 - eighth - - 5 - 4 - - down - continue - - - - G - 5 - - 12 - 1 - 16th - - 5 - 4 - - down - end - backward hook - - - - - - - C - 6 - - 40 - 1 - quarter - - 3 - 2 - - down - - - - - - - D - 6 - - 40 - 1 - quarter - - 3 - 2 - - down - - - - 8 - 1 - 16th - - 15 - 8 - - - - - 5 - 16th - - - 4 - 16th - - - - - - - B - -1 - 5 - - 8 - 1 - 16th - flat - - 15 - 8 - - down - begin - begin - - - - B - 5 - - 8 - 1 - 16th - natural - - 15 - 8 - - down - continue - continue - - - - C - 6 - - 8 - 1 - 16th - - 15 - 8 - - down - continue - continue - - - - D - -1 - 6 - - 8 - 1 - 16th - flat - - 15 - 8 - - down - end - end - - - - - - - - 60 - 1 - quarter - - - light-heavy - - - - - diff --git a/docs/DevNotes/VoiceExperiment.xml b/docs/DevNotes/VoiceExperiment.xml deleted file mode 100644 index 011d75e3f..000000000 --- a/docs/DevNotes/VoiceExperiment.xml +++ /dev/null @@ -1,155 +0,0 @@ - - - - - - Finale for Mac - 2016-09-12 - - - - - - - - - - 7.2319 - 40 - - - 1545 - 1194 - - 70 - 70 - 88 - 88 - - - - - 0 - 0 - - 121 - 70 - - - 0.7487 - 5 - 0.7487 - 0.7487 - 5 - 0.7487 - 0.7487 - 0.7487 - 0.7487 - 0.7487 - 60 - 60 - 120 - 8 - - - - - - Score - - - - MusicXML Part - - SmartMusic SoftSynth 1 - - - 1 - 15489 - 1 - 80 - 0 - - - - - - - - - - 70 - 0 - - 211 - - system - - - 2 - - 0 - major - - - 2 - - G - 2 - - - - - - F - 5 - - 2 - 2 - quarter - down - 1 - - - - B - 4 - - 2 - - quarter - down - 1 - - - - F - 4 - - 2 - - quarter - up - 1 - - - - C - 5 - - 2 - - quarter - down - 1 - - - light-heavy - - - - - diff --git a/docs/OldCode/Enums.old.cpp b/docs/OldCode/Enums.old.cpp deleted file mode 100755 index b31e8093c..000000000 --- a/docs/OldCode/Enums.old.cpp +++ /dev/null @@ -1,3895 +0,0 @@ -// MusicXML Class Library -// Copyright (c) by Matthew James Briggs -// Distributed under the MIT License - -#include "mx/core/Enums.h" - -namespace mx -{ - namespace core - { - AboveBelow parseAboveBelow( const std::string& value ) - { - if ( value == "above" ) { return AboveBelow::above; } - else if ( value == "below" ) { return AboveBelow::below; } - return AboveBelow::above; - } - - - std::string toString( const AboveBelow value ) - { - switch ( value ) - { - case AboveBelow::above: return "above"; - case AboveBelow::below: return "below"; - default: break; - } - return "above"; - } - - - std::ostream& toStream( std::ostream& os, const AboveBelow value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const AboveBelow value ) - { - return toStream( os, value ); - } - - CssFontSize parseCssFontSize( const std::string& value ) - { - if ( value == "xx-small" ) { return CssFontSize::xxSmall; } - else if ( value == "x-small" ) { return CssFontSize::xSmall; } - else if ( value == "small" ) { return CssFontSize::small; } - else if ( value == "medium" ) { return CssFontSize::medium; } - else if ( value == "large" ) { return CssFontSize::large; } - else if ( value == "x-large" ) { return CssFontSize::xLarge; } - else if ( value == "xx-large" ) { return CssFontSize::xxLarge; } - return CssFontSize::xxSmall; - } - - - std::string toString( const CssFontSize value ) - { - switch ( value ) - { - case CssFontSize::xxSmall: return "xx-small"; - case CssFontSize::xSmall: return "x-small"; - case CssFontSize::small: return "small"; - case CssFontSize::medium: return "medium"; - case CssFontSize::large: return "large"; - case CssFontSize::xLarge: return "x-large"; - case CssFontSize::xxLarge: return "xx-large"; - default: break; - } - return "xx-small"; - } - - - std::ostream& toStream( std::ostream& os, const CssFontSize value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const CssFontSize value ) - { - return toStream( os, value ); - } - - EnclosureShape parseEnclosureShape( const std::string& value ) - { - if ( value == "rectangle" ) { return EnclosureShape::rectangle; } - else if ( value == "square" ) { return EnclosureShape::square; } - else if ( value == "oval" ) { return EnclosureShape::oval; } - else if ( value == "circle" ) { return EnclosureShape::circle; } - else if ( value == "bracket" ) { return EnclosureShape::bracket; } - else if ( value == "triangle" ) { return EnclosureShape::triangle; } - else if ( value == "diamond" ) { return EnclosureShape::diamond; } - else if ( value == "none" ) { return EnclosureShape::none; } - return EnclosureShape::rectangle; - } - - - std::string toString( const EnclosureShape value ) - { - switch ( value ) - { - case EnclosureShape::rectangle: return "rectangle"; - case EnclosureShape::square: return "square"; - case EnclosureShape::oval: return "oval"; - case EnclosureShape::circle: return "circle"; - case EnclosureShape::bracket: return "bracket"; - case EnclosureShape::triangle: return "triangle"; - case EnclosureShape::diamond: return "diamond"; - case EnclosureShape::none: return "none"; - default: break; - } - return "rectangle"; - } - - - std::ostream& toStream( std::ostream& os, const EnclosureShape value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const EnclosureShape value ) - { - return toStream( os, value ); - } - - FermataShape parseFermataShape( const std::string& value ) - { - if ( value == "normal" ) { return FermataShape::normal; } - else if ( value == "angled" ) { return FermataShape::angled; } - else if ( value == "square" ) { return FermataShape::square; } - else if ( value == "" ) { return FermataShape::emptystring; } - return FermataShape::normal; - } - - - std::string toString( const FermataShape value ) - { - switch ( value ) - { - case FermataShape::normal: return "normal"; - case FermataShape::angled: return "angled"; - case FermataShape::square: return "square"; - case FermataShape::emptystring: return ""; - default: break; - } - return "normal"; - } - - - std::ostream& toStream( std::ostream& os, const FermataShape value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const FermataShape value ) - { - return toStream( os, value ); - } - - FontStyle parseFontStyle( const std::string& value ) - { - if ( value == "normal" ) { return FontStyle::normal; } - else if ( value == "italic" ) { return FontStyle::italic; } - return FontStyle::normal; - } - - - std::string toString( const FontStyle value ) - { - switch ( value ) - { - case FontStyle::normal: return "normal"; - case FontStyle::italic: return "italic"; - default: break; - } - return "normal"; - } - - - std::ostream& toStream( std::ostream& os, const FontStyle value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const FontStyle value ) - { - return toStream( os, value ); - } - - FontWeight parseFontWeight( const std::string& value ) - { - if ( value == "normal" ) { return FontWeight::normal; } - else if ( value == "bold" ) { return FontWeight::bold; } - return FontWeight::normal; - } - - - std::string toString( const FontWeight value ) - { - switch ( value ) - { - case FontWeight::normal: return "normal"; - case FontWeight::bold: return "bold"; - default: break; - } - return "normal"; - } - - - std::ostream& toStream( std::ostream& os, const FontWeight value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const FontWeight value ) - { - return toStream( os, value ); - } - - LeftCenterRight parseLeftCenterRight( const std::string& value ) - { - if ( value == "left" ) { return LeftCenterRight::left; } - else if ( value == "center" ) { return LeftCenterRight::center; } - else if ( value == "right" ) { return LeftCenterRight::right; } - return LeftCenterRight::left; - } - - - std::string toString( const LeftCenterRight value ) - { - switch ( value ) - { - case LeftCenterRight::left: return "left"; - case LeftCenterRight::center: return "center"; - case LeftCenterRight::right: return "right"; - default: break; - } - return "left"; - } - - - std::ostream& toStream( std::ostream& os, const LeftCenterRight value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const LeftCenterRight value ) - { - return toStream( os, value ); - } - - LeftRight parseLeftRight( const std::string& value ) - { - if ( value == "left" ) { return LeftRight::left; } - else if ( value == "right" ) { return LeftRight::right; } - return LeftRight::left; - } - - - std::string toString( const LeftRight value ) - { - switch ( value ) - { - case LeftRight::left: return "left"; - case LeftRight::right: return "right"; - default: break; - } - return "left"; - } - - - std::ostream& toStream( std::ostream& os, const LeftRight value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const LeftRight value ) - { - return toStream( os, value ); - } - - LineShape parseLineShape( const std::string& value ) - { - if ( value == "straight" ) { return LineShape::straight; } - else if ( value == "curved" ) { return LineShape::curved; } - return LineShape::straight; - } - - - std::string toString( const LineShape value ) - { - switch ( value ) - { - case LineShape::straight: return "straight"; - case LineShape::curved: return "curved"; - default: break; - } - return "straight"; - } - - - std::ostream& toStream( std::ostream& os, const LineShape value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const LineShape value ) - { - return toStream( os, value ); - } - - LineType parseLineType( const std::string& value ) - { - if ( value == "solid" ) { return LineType::solid; } - else if ( value == "dashed" ) { return LineType::dashed; } - else if ( value == "dotted" ) { return LineType::dotted; } - else if ( value == "wavy" ) { return LineType::wavy; } - return LineType::solid; - } - - - std::string toString( const LineType value ) - { - switch ( value ) - { - case LineType::solid: return "solid"; - case LineType::dashed: return "dashed"; - case LineType::dotted: return "dotted"; - case LineType::wavy: return "wavy"; - default: break; - } - return "solid"; - } - - - std::ostream& toStream( std::ostream& os, const LineType value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const LineType value ) - { - return toStream( os, value ); - } - - MuteEnum parseMuteEnum( const std::string& value ) - { - if ( value == "on" ) { return MuteEnum::on; } - else if ( value == "off" ) { return MuteEnum::off; } - else if ( value == "straight" ) { return MuteEnum::straight; } - else if ( value == "cup" ) { return MuteEnum::cup; } - else if ( value == "harmon-no-stem" ) { return MuteEnum::harmonNoStem; } - else if ( value == "harmon-stem" ) { return MuteEnum::harmonStem; } - else if ( value == "bucket" ) { return MuteEnum::bucket; } - else if ( value == "plunger" ) { return MuteEnum::plunger; } - else if ( value == "hat" ) { return MuteEnum::hat; } - else if ( value == "solotone" ) { return MuteEnum::solotone; } - else if ( value == "practice" ) { return MuteEnum::practice; } - else if ( value == "stop-mute" ) { return MuteEnum::stopMute; } - else if ( value == "stop-hand" ) { return MuteEnum::stopHand; } - else if ( value == "echo" ) { return MuteEnum::echo; } - else if ( value == "palm" ) { return MuteEnum::palm; } - return MuteEnum::on; - } - - - std::string toString( const MuteEnum value ) - { - switch ( value ) - { - case MuteEnum::on: return "on"; - case MuteEnum::off: return "off"; - case MuteEnum::straight: return "straight"; - case MuteEnum::cup: return "cup"; - case MuteEnum::harmonNoStem: return "harmon-no-stem"; - case MuteEnum::harmonStem: return "harmon-stem"; - case MuteEnum::bucket: return "bucket"; - case MuteEnum::plunger: return "plunger"; - case MuteEnum::hat: return "hat"; - case MuteEnum::solotone: return "solotone"; - case MuteEnum::practice: return "practice"; - case MuteEnum::stopMute: return "stop-mute"; - case MuteEnum::stopHand: return "stop-hand"; - case MuteEnum::echo: return "echo"; - case MuteEnum::palm: return "palm"; - default: break; - } - return "on"; - } - - - std::ostream& toStream( std::ostream& os, const MuteEnum value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const MuteEnum value ) - { - return toStream( os, value ); - } - - OverUnder parseOverUnder( const std::string& value ) - { - if ( value == "over" ) { return OverUnder::over; } - else if ( value == "under" ) { return OverUnder::under; } - return OverUnder::over; - } - - - std::string toString( const OverUnder value ) - { - switch ( value ) - { - case OverUnder::over: return "over"; - case OverUnder::under: return "under"; - default: break; - } - return "over"; - } - - - std::ostream& toStream( std::ostream& os, const OverUnder value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const OverUnder value ) - { - return toStream( os, value ); - } - - SemiPitchedEnum parseSemiPitchedEnum( const std::string& value ) - { - if ( value == "high" ) { return SemiPitchedEnum::high; } - else if ( value == "medium-high" ) { return SemiPitchedEnum::mediumHigh; } - else if ( value == "medium" ) { return SemiPitchedEnum::medium; } - else if ( value == "medium-low" ) { return SemiPitchedEnum::mediumLow; } - else if ( value == "low" ) { return SemiPitchedEnum::low; } - else if ( value == "very-low" ) { return SemiPitchedEnum::veryLow; } - return SemiPitchedEnum::high; - } - - - std::string toString( const SemiPitchedEnum value ) - { - switch ( value ) - { - case SemiPitchedEnum::high: return "high"; - case SemiPitchedEnum::mediumHigh: return "medium-high"; - case SemiPitchedEnum::medium: return "medium"; - case SemiPitchedEnum::mediumLow: return "medium-low"; - case SemiPitchedEnum::low: return "low"; - case SemiPitchedEnum::veryLow: return "very-low"; - default: break; - } - return "high"; - } - - - std::ostream& toStream( std::ostream& os, const SemiPitchedEnum value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const SemiPitchedEnum value ) - { - return toStream( os, value ); - } - - StartNote parseStartNote( const std::string& value ) - { - if ( value == "upper" ) { return StartNote::upper; } - else if ( value == "main" ) { return StartNote::main; } - else if ( value == "below" ) { return StartNote::below; } - return StartNote::upper; - } - - - std::string toString( const StartNote value ) - { - switch ( value ) - { - case StartNote::upper: return "upper"; - case StartNote::main: return "main"; - case StartNote::below: return "below"; - default: break; - } - return "upper"; - } - - - std::ostream& toStream( std::ostream& os, const StartNote value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const StartNote value ) - { - return toStream( os, value ); - } - - StartStop parseStartStop( const std::string& value ) - { - if ( value == "start" ) { return StartStop::start; } - else if ( value == "stop" ) { return StartStop::stop; } - return StartStop::start; - } - - - std::string toString( const StartStop value ) - { - switch ( value ) - { - case StartStop::start: return "start"; - case StartStop::stop: return "stop"; - default: break; - } - return "start"; - } - - - std::ostream& toStream( std::ostream& os, const StartStop value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const StartStop value ) - { - return toStream( os, value ); - } - - StartStopContinue parseStartStopContinue( const std::string& value ) - { - if ( value == "start" ) { return StartStopContinue::start; } - else if ( value == "stop" ) { return StartStopContinue::stop; } - else if ( value == "continue" ) { return StartStopContinue::continue_; } - return StartStopContinue::start; - } - - - std::string toString( const StartStopContinue value ) - { - switch ( value ) - { - case StartStopContinue::start: return "start"; - case StartStopContinue::stop: return "stop"; - case StartStopContinue::continue_: return "continue"; - default: break; - } - return "start"; - } - - - std::ostream& toStream( std::ostream& os, const StartStopContinue value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const StartStopContinue value ) - { - return toStream( os, value ); - } - - StartStopSingle parseStartStopSingle( const std::string& value ) - { - if ( value == "start" ) { return StartStopSingle::start; } - else if ( value == "stop" ) { return StartStopSingle::stop; } - else if ( value == "single" ) { return StartStopSingle::single; } - return StartStopSingle::start; - } - - - std::string toString( const StartStopSingle value ) - { - switch ( value ) - { - case StartStopSingle::start: return "start"; - case StartStopSingle::stop: return "stop"; - case StartStopSingle::single: return "single"; - default: break; - } - return "start"; - } - - - std::ostream& toStream( std::ostream& os, const StartStopSingle value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const StartStopSingle value ) - { - return toStream( os, value ); - } - - SymbolSize parseSymbolSize( const std::string& value ) - { - if ( value == "full" ) { return SymbolSize::full; } - else if ( value == "cue" ) { return SymbolSize::cue; } - else if ( value == "large" ) { return SymbolSize::large; } - return SymbolSize::full; - } - - - std::string toString( const SymbolSize value ) - { - switch ( value ) - { - case SymbolSize::full: return "full"; - case SymbolSize::cue: return "cue"; - case SymbolSize::large: return "large"; - default: break; - } - return "full"; - } - - - std::ostream& toStream( std::ostream& os, const SymbolSize value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const SymbolSize value ) - { - return toStream( os, value ); - } - - TextDirection parseTextDirection( const std::string& value ) - { - if ( value == "ltr" ) { return TextDirection::ltr; } - else if ( value == "rtl" ) { return TextDirection::rtl; } - else if ( value == "lro" ) { return TextDirection::lro; } - else if ( value == "rlo" ) { return TextDirection::rlo; } - return TextDirection::ltr; - } - - - std::string toString( const TextDirection value ) - { - switch ( value ) - { - case TextDirection::ltr: return "ltr"; - case TextDirection::rtl: return "rtl"; - case TextDirection::lro: return "lro"; - case TextDirection::rlo: return "rlo"; - default: break; - } - return "ltr"; - } - - - std::ostream& toStream( std::ostream& os, const TextDirection value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const TextDirection value ) - { - return toStream( os, value ); - } - - TopBottom parseTopBottom( const std::string& value ) - { - if ( value == "top" ) { return TopBottom::top; } - else if ( value == "bottom" ) { return TopBottom::bottom; } - return TopBottom::top; - } - - - std::string toString( const TopBottom value ) - { - switch ( value ) - { - case TopBottom::top: return "top"; - case TopBottom::bottom: return "bottom"; - default: break; - } - return "top"; - } - - - std::ostream& toStream( std::ostream& os, const TopBottom value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const TopBottom value ) - { - return toStream( os, value ); - } - - TrillStep parseTrillStep( const std::string& value ) - { - if ( value == "whole" ) { return TrillStep::whole; } - else if ( value == "half" ) { return TrillStep::half; } - else if ( value == "unison" ) { return TrillStep::unison; } - return TrillStep::whole; - } - - - std::string toString( const TrillStep value ) - { - switch ( value ) - { - case TrillStep::whole: return "whole"; - case TrillStep::half: return "half"; - case TrillStep::unison: return "unison"; - default: break; - } - return "whole"; - } - - - std::ostream& toStream( std::ostream& os, const TrillStep value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const TrillStep value ) - { - return toStream( os, value ); - } - - TwoNoteTurn parseTwoNoteTurn( const std::string& value ) - { - if ( value == "whole" ) { return TwoNoteTurn::whole; } - else if ( value == "half" ) { return TwoNoteTurn::half; } - else if ( value == "none" ) { return TwoNoteTurn::none; } - return TwoNoteTurn::whole; - } - - - std::string toString( const TwoNoteTurn value ) - { - switch ( value ) - { - case TwoNoteTurn::whole: return "whole"; - case TwoNoteTurn::half: return "half"; - case TwoNoteTurn::none: return "none"; - default: break; - } - return "whole"; - } - - - std::ostream& toStream( std::ostream& os, const TwoNoteTurn value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const TwoNoteTurn value ) - { - return toStream( os, value ); - } - - UpDown parseUpDown( const std::string& value ) - { - if ( value == "up" ) { return UpDown::up; } - else if ( value == "down" ) { return UpDown::down; } - return UpDown::up; - } - - - std::string toString( const UpDown value ) - { - switch ( value ) - { - case UpDown::up: return "up"; - case UpDown::down: return "down"; - default: break; - } - return "up"; - } - - - std::ostream& toStream( std::ostream& os, const UpDown value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const UpDown value ) - { - return toStream( os, value ); - } - - UprightInverted parseUprightInverted( const std::string& value ) - { - if ( value == "upright" ) { return UprightInverted::upright; } - else if ( value == "inverted" ) { return UprightInverted::inverted; } - return UprightInverted::upright; - } - - - std::string toString( const UprightInverted value ) - { - switch ( value ) - { - case UprightInverted::upright: return "upright"; - case UprightInverted::inverted: return "inverted"; - default: break; - } - return "upright"; - } - - - std::ostream& toStream( std::ostream& os, const UprightInverted value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const UprightInverted value ) - { - return toStream( os, value ); - } - - Valign parseValign( const std::string& value ) - { - if ( value == "top" ) { return Valign::top; } - else if ( value == "middle" ) { return Valign::middle; } - else if ( value == "bottom" ) { return Valign::bottom; } - else if ( value == "baseline" ) { return Valign::baseline; } - return Valign::top; - } - - - std::string toString( const Valign value ) - { - switch ( value ) - { - case Valign::top: return "top"; - case Valign::middle: return "middle"; - case Valign::bottom: return "bottom"; - case Valign::baseline: return "baseline"; - default: break; - } - return "top"; - } - - - std::ostream& toStream( std::ostream& os, const Valign value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const Valign value ) - { - return toStream( os, value ); - } - - ValignImage parseValignImage( const std::string& value ) - { - if ( value == "top" ) { return ValignImage::top; } - else if ( value == "middle" ) { return ValignImage::middle; } - else if ( value == "bottom" ) { return ValignImage::bottom; } - return ValignImage::top; - } - - - std::string toString( const ValignImage value ) - { - switch ( value ) - { - case ValignImage::top: return "top"; - case ValignImage::middle: return "middle"; - case ValignImage::bottom: return "bottom"; - default: break; - } - return "top"; - } - - - std::ostream& toStream( std::ostream& os, const ValignImage value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const ValignImage value ) - { - return toStream( os, value ); - } - - YesNo parseYesNo( const std::string& value ) - { - if ( value == "yes" ) { return YesNo::yes; } - else if ( value == "no" ) { return YesNo::no; } - return YesNo::yes; - } - - - std::string toString( const YesNo value ) - { - switch ( value ) - { - case YesNo::yes: return "yes"; - case YesNo::no: return "no"; - default: break; - } - return "yes"; - } - - - std::ostream& toStream( std::ostream& os, const YesNo value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const YesNo value ) - { - return toStream( os, value ); - } - - CancelLocation parseCancelLocation( const std::string& value ) - { - if ( value == "left" ) { return CancelLocation::left; } - else if ( value == "right" ) { return CancelLocation::right; } - else if ( value == "before-barline" ) { return CancelLocation::beforeBarline; } - return CancelLocation::left; - } - - - std::string toString( const CancelLocation value ) - { - switch ( value ) - { - case CancelLocation::left: return "left"; - case CancelLocation::right: return "right"; - case CancelLocation::beforeBarline: return "before-barline"; - default: break; - } - return "left"; - } - - - std::ostream& toStream( std::ostream& os, const CancelLocation value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const CancelLocation value ) - { - return toStream( os, value ); - } - - ClefSign parseClefSign( const std::string& value ) - { - if ( value == "G" ) { return ClefSign::g; } - else if ( value == "F" ) { return ClefSign::f; } - else if ( value == "C" ) { return ClefSign::c; } - else if ( value == "percussion" ) { return ClefSign::percussion; } - else if ( value == "TAB" ) { return ClefSign::tab; } - else if ( value == "jianpu" ) { return ClefSign::jianpu; } - else if ( value == "none" ) { return ClefSign::none; } - return ClefSign::g; - } - - - std::string toString( const ClefSign value ) - { - switch ( value ) - { - case ClefSign::g: return "G"; - case ClefSign::f: return "F"; - case ClefSign::c: return "C"; - case ClefSign::percussion: return "percussion"; - case ClefSign::tab: return "TAB"; - case ClefSign::jianpu: return "jianpu"; - case ClefSign::none: return "none"; - default: break; - } - return "G"; - } - - - std::ostream& toStream( std::ostream& os, const ClefSign value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const ClefSign value ) - { - return toStream( os, value ); - } - - ShowFrets parseShowFrets( const std::string& value ) - { - if ( value == "numbers" ) { return ShowFrets::numbers; } - else if ( value == "letters" ) { return ShowFrets::letters; } - return ShowFrets::numbers; - } - - - std::string toString( const ShowFrets value ) - { - switch ( value ) - { - case ShowFrets::numbers: return "numbers"; - case ShowFrets::letters: return "letters"; - default: break; - } - return "numbers"; - } - - - std::ostream& toStream( std::ostream& os, const ShowFrets value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const ShowFrets value ) - { - return toStream( os, value ); - } - - StaffTypeEnum parseStaffTypeEnum( const std::string& value ) - { - if ( value == "ossia" ) { return StaffTypeEnum::ossia; } - else if ( value == "cue" ) { return StaffTypeEnum::cue; } - else if ( value == "editorial" ) { return StaffTypeEnum::editorial; } - else if ( value == "regular" ) { return StaffTypeEnum::regular; } - else if ( value == "alternate" ) { return StaffTypeEnum::alternate; } - return StaffTypeEnum::ossia; - } - - - std::string toString( const StaffTypeEnum value ) - { - switch ( value ) - { - case StaffTypeEnum::ossia: return "ossia"; - case StaffTypeEnum::cue: return "cue"; - case StaffTypeEnum::editorial: return "editorial"; - case StaffTypeEnum::regular: return "regular"; - case StaffTypeEnum::alternate: return "alternate"; - default: break; - } - return "ossia"; - } - - - std::ostream& toStream( std::ostream& os, const StaffTypeEnum value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const StaffTypeEnum value ) - { - return toStream( os, value ); - } - - TimeRelationEnum parseTimeRelationEnum( const std::string& value ) - { - if ( value == "parentheses" ) { return TimeRelationEnum::parentheses; } - else if ( value == "bracket" ) { return TimeRelationEnum::bracket; } - else if ( value == "equals" ) { return TimeRelationEnum::equals; } - else if ( value == "slash" ) { return TimeRelationEnum::slash; } - else if ( value == "space" ) { return TimeRelationEnum::space; } - else if ( value == "hyphen" ) { return TimeRelationEnum::hyphen; } - return TimeRelationEnum::parentheses; - } - - - std::string toString( const TimeRelationEnum value ) - { - switch ( value ) - { - case TimeRelationEnum::parentheses: return "parentheses"; - case TimeRelationEnum::bracket: return "bracket"; - case TimeRelationEnum::equals: return "equals"; - case TimeRelationEnum::slash: return "slash"; - case TimeRelationEnum::space: return "space"; - case TimeRelationEnum::hyphen: return "hyphen"; - default: break; - } - return "parentheses"; - } - - - std::ostream& toStream( std::ostream& os, const TimeRelationEnum value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const TimeRelationEnum value ) - { - return toStream( os, value ); - } - - TimeSeparator parseTimeSeparator( const std::string& value ) - { - if ( value == "none" ) { return TimeSeparator::none; } - else if ( value == "horizontal" ) { return TimeSeparator::horizontal; } - else if ( value == "diagonal" ) { return TimeSeparator::diagonal; } - else if ( value == "vertical" ) { return TimeSeparator::vertical; } - else if ( value == "adjacent" ) { return TimeSeparator::adjacent; } - return TimeSeparator::none; - } - - - std::string toString( const TimeSeparator value ) - { - switch ( value ) - { - case TimeSeparator::none: return "none"; - case TimeSeparator::horizontal: return "horizontal"; - case TimeSeparator::diagonal: return "diagonal"; - case TimeSeparator::vertical: return "vertical"; - case TimeSeparator::adjacent: return "adjacent"; - default: break; - } - return "none"; - } - - - std::ostream& toStream( std::ostream& os, const TimeSeparator value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const TimeSeparator value ) - { - return toStream( os, value ); - } - - TimeSymbol parseTimeSymbol( const std::string& value ) - { - if ( value == "common" ) { return TimeSymbol::common; } - else if ( value == "cut" ) { return TimeSymbol::cut; } - else if ( value == "single-number" ) { return TimeSymbol::singleNumber; } - else if ( value == "note" ) { return TimeSymbol::note; } - else if ( value == "dotted-note" ) { return TimeSymbol::dottedNote; } - else if ( value == "normal" ) { return TimeSymbol::normal; } - return TimeSymbol::common; - } - - - std::string toString( const TimeSymbol value ) - { - switch ( value ) - { - case TimeSymbol::common: return "common"; - case TimeSymbol::cut: return "cut"; - case TimeSymbol::singleNumber: return "single-number"; - case TimeSymbol::note: return "note"; - case TimeSymbol::dottedNote: return "dotted-note"; - case TimeSymbol::normal: return "normal"; - default: break; - } - return "common"; - } - - - std::ostream& toStream( std::ostream& os, const TimeSymbol value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const TimeSymbol value ) - { - return toStream( os, value ); - } - - BackwardForward parseBackwardForward( const std::string& value ) - { - if ( value == "backward" ) { return BackwardForward::backward; } - else if ( value == "forward" ) { return BackwardForward::forward; } - return BackwardForward::backward; - } - - - std::string toString( const BackwardForward value ) - { - switch ( value ) - { - case BackwardForward::backward: return "backward"; - case BackwardForward::forward: return "forward"; - default: break; - } - return "backward"; - } - - - std::ostream& toStream( std::ostream& os, const BackwardForward value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const BackwardForward value ) - { - return toStream( os, value ); - } - - BarStyleEnum parseBarStyleEnum( const std::string& value ) - { - if ( value == "regular" ) { return BarStyleEnum::regular; } - else if ( value == "dotted" ) { return BarStyleEnum::dotted; } - else if ( value == "dashed" ) { return BarStyleEnum::dashed; } - else if ( value == "heavy" ) { return BarStyleEnum::heavy; } - else if ( value == "light-light" ) { return BarStyleEnum::lightLight; } - else if ( value == "light-heavy" ) { return BarStyleEnum::lightHeavy; } - else if ( value == "heavy-light" ) { return BarStyleEnum::heavyLight; } - else if ( value == "heavy-heavy" ) { return BarStyleEnum::heavyHeavy; } - else if ( value == "tick" ) { return BarStyleEnum::tick; } - else if ( value == "short" ) { return BarStyleEnum::short_; } - else if ( value == "none" ) { return BarStyleEnum::none; } - return BarStyleEnum::regular; - } - - - std::string toString( const BarStyleEnum value ) - { - switch ( value ) - { - case BarStyleEnum::regular: return "regular"; - case BarStyleEnum::dotted: return "dotted"; - case BarStyleEnum::dashed: return "dashed"; - case BarStyleEnum::heavy: return "heavy"; - case BarStyleEnum::lightLight: return "light-light"; - case BarStyleEnum::lightHeavy: return "light-heavy"; - case BarStyleEnum::heavyLight: return "heavy-light"; - case BarStyleEnum::heavyHeavy: return "heavy-heavy"; - case BarStyleEnum::tick: return "tick"; - case BarStyleEnum::short_: return "short"; - case BarStyleEnum::none: return "none"; - default: break; - } - return "regular"; - } - - - std::ostream& toStream( std::ostream& os, const BarStyleEnum value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const BarStyleEnum value ) - { - return toStream( os, value ); - } - - RightLeftMiddle parseRightLeftMiddle( const std::string& value ) - { - if ( value == "right" ) { return RightLeftMiddle::right; } - else if ( value == "left" ) { return RightLeftMiddle::left; } - else if ( value == "middle" ) { return RightLeftMiddle::middle; } - return RightLeftMiddle::right; - } - - - std::string toString( const RightLeftMiddle value ) - { - switch ( value ) - { - case RightLeftMiddle::right: return "right"; - case RightLeftMiddle::left: return "left"; - case RightLeftMiddle::middle: return "middle"; - default: break; - } - return "right"; - } - - - std::ostream& toStream( std::ostream& os, const RightLeftMiddle value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const RightLeftMiddle value ) - { - return toStream( os, value ); - } - - StartStopDiscontinue parseStartStopDiscontinue( const std::string& value ) - { - if ( value == "start" ) { return StartStopDiscontinue::start; } - else if ( value == "stop" ) { return StartStopDiscontinue::stop; } - else if ( value == "discontinue" ) { return StartStopDiscontinue::discontinue; } - return StartStopDiscontinue::start; - } - - - std::string toString( const StartStopDiscontinue value ) - { - switch ( value ) - { - case StartStopDiscontinue::start: return "start"; - case StartStopDiscontinue::stop: return "stop"; - case StartStopDiscontinue::discontinue: return "discontinue"; - default: break; - } - return "start"; - } - - - std::ostream& toStream( std::ostream& os, const StartStopDiscontinue value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const StartStopDiscontinue value ) - { - return toStream( os, value ); - } - - Winged parseWinged( const std::string& value ) - { - if ( value == "none" ) { return Winged::none; } - else if ( value == "straight" ) { return Winged::straight; } - else if ( value == "curved" ) { return Winged::curved; } - else if ( value == "double-straight" ) { return Winged::doubleStraight; } - else if ( value == "double-curved" ) { return Winged::doubleCurved; } - return Winged::none; - } - - - std::string toString( const Winged value ) - { - switch ( value ) - { - case Winged::none: return "none"; - case Winged::straight: return "straight"; - case Winged::curved: return "curved"; - case Winged::doubleStraight: return "double-straight"; - case Winged::doubleCurved: return "double-curved"; - default: break; - } - return "none"; - } - - - std::ostream& toStream( std::ostream& os, const Winged value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const Winged value ) - { - return toStream( os, value ); - } - - BeaterValue parseBeaterValue( const std::string& value ) - { - if ( value == "bow" ) { return BeaterValue::bow; } - else if ( value == "chime hammer" ) { return BeaterValue::chimeHammer; } - else if ( value == "coin" ) { return BeaterValue::coin; } - else if ( value == "finger" ) { return BeaterValue::finger; } - else if ( value == "fingernail" ) { return BeaterValue::fingernail; } - else if ( value == "fist" ) { return BeaterValue::fist; } - else if ( value == "guiro scraper" ) { return BeaterValue::guiroScraper; } - else if ( value == "hammer" ) { return BeaterValue::hammer; } - else if ( value == "hand" ) { return BeaterValue::hand; } - else if ( value == "jazz stick" ) { return BeaterValue::jazzStick; } - else if ( value == "knitting needle" ) { return BeaterValue::knittingNeedle; } - else if ( value == "metal hammer" ) { return BeaterValue::metalHammer; } - else if ( value == "snare stick" ) { return BeaterValue::snareStick; } - else if ( value == "spoon mallet" ) { return BeaterValue::spoonMallet; } - else if ( value == "triangle beater" ) { return BeaterValue::triangleBeater; } - else if ( value == "triangle beater plain" ) { return BeaterValue::triangleBeaterPlain; } - else if ( value == "wire brush" ) { return BeaterValue::wireBrush; } - return BeaterValue::bow; - } - - - std::string toString( const BeaterValue value ) - { - switch ( value ) - { - case BeaterValue::bow: return "bow"; - case BeaterValue::chimeHammer: return "chime hammer"; - case BeaterValue::coin: return "coin"; - case BeaterValue::finger: return "finger"; - case BeaterValue::fingernail: return "fingernail"; - case BeaterValue::fist: return "fist"; - case BeaterValue::guiroScraper: return "guiro scraper"; - case BeaterValue::hammer: return "hammer"; - case BeaterValue::hand: return "hand"; - case BeaterValue::jazzStick: return "jazz stick"; - case BeaterValue::knittingNeedle: return "knitting needle"; - case BeaterValue::metalHammer: return "metal hammer"; - case BeaterValue::snareStick: return "snare stick"; - case BeaterValue::spoonMallet: return "spoon mallet"; - case BeaterValue::triangleBeater: return "triangle beater"; - case BeaterValue::triangleBeaterPlain: return "triangle beater plain"; - case BeaterValue::wireBrush: return "wire brush"; - default: break; - } - return "bow"; - } - - - std::ostream& toStream( std::ostream& os, const BeaterValue value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const BeaterValue value ) - { - return toStream( os, value ); - } - - DegreeSymbolValue parseDegreeSymbolValue( const std::string& value ) - { - if ( value == "major" ) { return DegreeSymbolValue::major; } - else if ( value == "minor" ) { return DegreeSymbolValue::minor; } - else if ( value == "augmented" ) { return DegreeSymbolValue::augmented; } - else if ( value == "diminished" ) { return DegreeSymbolValue::diminished; } - else if ( value == "half-diminished" ) { return DegreeSymbolValue::halfDiminished; } - return DegreeSymbolValue::major; - } - - - std::string toString( const DegreeSymbolValue value ) - { - switch ( value ) - { - case DegreeSymbolValue::major: return "major"; - case DegreeSymbolValue::minor: return "minor"; - case DegreeSymbolValue::augmented: return "augmented"; - case DegreeSymbolValue::diminished: return "diminished"; - case DegreeSymbolValue::halfDiminished: return "half-diminished"; - default: break; - } - return "major"; - } - - - std::ostream& toStream( std::ostream& os, const DegreeSymbolValue value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const DegreeSymbolValue value ) - { - return toStream( os, value ); - } - - DegreeTypeValue parseDegreeTypeValue( const std::string& value ) - { - if ( value == "add" ) { return DegreeTypeValue::add; } - else if ( value == "alter" ) { return DegreeTypeValue::alter; } - else if ( value == "subtract" ) { return DegreeTypeValue::subtract; } - return DegreeTypeValue::add; - } - - - std::string toString( const DegreeTypeValue value ) - { - switch ( value ) - { - case DegreeTypeValue::add: return "add"; - case DegreeTypeValue::alter: return "alter"; - case DegreeTypeValue::subtract: return "subtract"; - default: break; - } - return "add"; - } - - - std::ostream& toStream( std::ostream& os, const DegreeTypeValue value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const DegreeTypeValue value ) - { - return toStream( os, value ); - } - - EffectEnum parseEffectEnum( const std::string& value ) - { - if ( value == "anvil" ) { return EffectEnum::anvil; } - else if ( value == "auto horn" ) { return EffectEnum::autoHorn; } - else if ( value == "bird whistle" ) { return EffectEnum::birdWhistle; } - else if ( value == "cannon" ) { return EffectEnum::cannon; } - else if ( value == "duck call" ) { return EffectEnum::duckCall; } - else if ( value == "gun shot" ) { return EffectEnum::gunShot; } - else if ( value == "klaxon horn" ) { return EffectEnum::klaxonHorn; } - else if ( value == "lions roar" ) { return EffectEnum::lionsRoar; } - else if ( value == "police whistle" ) { return EffectEnum::policeWhistle; } - else if ( value == "siren" ) { return EffectEnum::siren; } - else if ( value == "slide whistle" ) { return EffectEnum::slideWhistle; } - else if ( value == "thunder sheet" ) { return EffectEnum::thunderSheet; } - else if ( value == "wind machine" ) { return EffectEnum::windMachine; } - else if ( value == "wind whistle" ) { return EffectEnum::windWhistle; } - return EffectEnum::anvil; - } - - - std::string toString( const EffectEnum value ) - { - switch ( value ) - { - case EffectEnum::anvil: return "anvil"; - case EffectEnum::autoHorn: return "auto horn"; - case EffectEnum::birdWhistle: return "bird whistle"; - case EffectEnum::cannon: return "cannon"; - case EffectEnum::duckCall: return "duck call"; - case EffectEnum::gunShot: return "gun shot"; - case EffectEnum::klaxonHorn: return "klaxon horn"; - case EffectEnum::lionsRoar: return "lions roar"; - case EffectEnum::policeWhistle: return "police whistle"; - case EffectEnum::siren: return "siren"; - case EffectEnum::slideWhistle: return "slide whistle"; - case EffectEnum::thunderSheet: return "thunder sheet"; - case EffectEnum::windMachine: return "wind machine"; - case EffectEnum::windWhistle: return "wind whistle"; - default: break; - } - return "anvil"; - } - - - std::ostream& toStream( std::ostream& os, const EffectEnum value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const EffectEnum value ) - { - return toStream( os, value ); - } - - GlassEnum parseGlassEnum( const std::string& value ) - { - if ( value == "wind chimes" ) { return GlassEnum::windChimes; } - return GlassEnum::windChimes; - } - - - std::string toString( const GlassEnum value ) - { - switch ( value ) - { - case GlassEnum::windChimes: return "wind chimes"; - default: break; - } - return "wind chimes"; - } - - - std::ostream& toStream( std::ostream& os, const GlassEnum value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const GlassEnum value ) - { - return toStream( os, value ); - } - - HarmonyType parseHarmonyType( const std::string& value ) - { - if ( value == "explicit" ) { return HarmonyType::explicit_; } - else if ( value == "implied" ) { return HarmonyType::implied; } - else if ( value == "alternate" ) { return HarmonyType::alternate; } - return HarmonyType::explicit_; - } - - - std::string toString( const HarmonyType value ) - { - switch ( value ) - { - case HarmonyType::explicit_: return "explicit"; - case HarmonyType::implied: return "implied"; - case HarmonyType::alternate: return "alternate"; - default: break; - } - return "explicit"; - } - - - std::ostream& toStream( std::ostream& os, const HarmonyType value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const HarmonyType value ) - { - return toStream( os, value ); - } - - KindValue parseKindValue( const std::string& value ) - { - if ( value == "major" ) { return KindValue::major; } - else if ( value == "minor" ) { return KindValue::minor; } - else if ( value == "augmented" ) { return KindValue::augmented; } - else if ( value == "diminished" ) { return KindValue::diminished; } - else if ( value == "dominant" ) { return KindValue::dominant; } - else if ( value == "major-seventh" ) { return KindValue::majorSeventh; } - else if ( value == "minor-seventh" ) { return KindValue::minorSeventh; } - else if ( value == "diminished-seventh" ) { return KindValue::diminishedSeventh; } - else if ( value == "augmented-seventh" ) { return KindValue::augmentedSeventh; } - else if ( value == "half-diminished" ) { return KindValue::halfDiminished; } - else if ( value == "major-minor" ) { return KindValue::majorMinor; } - else if ( value == "major-sixth" ) { return KindValue::majorSixth; } - else if ( value == "minor-sixth" ) { return KindValue::minorSixth; } - else if ( value == "dominant-ninth" ) { return KindValue::dominantNinth; } - else if ( value == "major-ninth" ) { return KindValue::majorNinth; } - else if ( value == "minor-ninth" ) { return KindValue::minorNinth; } - else if ( value == "dominant-11th" ) { return KindValue::dominant11Th; } - else if ( value == "major-11th" ) { return KindValue::major11Th; } - else if ( value == "minor-11th" ) { return KindValue::minor11Th; } - else if ( value == "dominant-13th" ) { return KindValue::dominant13Th; } - else if ( value == "major-13th" ) { return KindValue::major13Th; } - else if ( value == "minor-13th" ) { return KindValue::minor13Th; } - else if ( value == "suspended-second" ) { return KindValue::suspendedSecond; } - else if ( value == "suspended-fourth" ) { return KindValue::suspendedFourth; } - else if ( value == "Neapolitan" ) { return KindValue::neapolitan; } - else if ( value == "Italian" ) { return KindValue::italian; } - else if ( value == "French" ) { return KindValue::french; } - else if ( value == "German" ) { return KindValue::german; } - else if ( value == "pedal" ) { return KindValue::pedal; } - else if ( value == "power" ) { return KindValue::power; } - else if ( value == "Tristan" ) { return KindValue::tristan; } - else if ( value == "other" ) { return KindValue::other; } - else if ( value == "none" ) { return KindValue::none; } - - // here are a couple of unsupported types but we will catch them - // most of these are coming from musuite_test_harmonly.xml - else if ( value == "dominant-seventh" ) { return KindValue::dominant; } - else if ( value == "neapolitan" ) { return KindValue::neapolitan; } - else if ( value == "italian" ) { return KindValue::italian; } - else if ( value == "french" ) { return KindValue::french; } - else if ( value == "german" ) { return KindValue::german; } - else if ( value == "french" ) { return KindValue::french; } - else if ( value == "tristan" ) { return KindValue::tristan; } - - return KindValue::none; - } - - - std::string toString( const KindValue value ) - { - switch ( value ) - { - case KindValue::major: return "major"; - case KindValue::minor: return "minor"; - case KindValue::augmented: return "augmented"; - case KindValue::diminished: return "diminished"; - case KindValue::dominant: return "dominant"; - case KindValue::majorSeventh: return "major-seventh"; - case KindValue::minorSeventh: return "minor-seventh"; - case KindValue::diminishedSeventh: return "diminished-seventh"; - case KindValue::augmentedSeventh: return "augmented-seventh"; - case KindValue::halfDiminished: return "half-diminished"; - case KindValue::majorMinor: return "major-minor"; - case KindValue::majorSixth: return "major-sixth"; - case KindValue::minorSixth: return "minor-sixth"; - case KindValue::dominantNinth: return "dominant-ninth"; - case KindValue::majorNinth: return "major-ninth"; - case KindValue::minorNinth: return "minor-ninth"; - case KindValue::dominant11Th: return "dominant-11th"; - case KindValue::major11Th: return "major-11th"; - case KindValue::minor11Th: return "minor-11th"; - case KindValue::dominant13Th: return "dominant-13th"; - case KindValue::major13Th: return "major-13th"; - case KindValue::minor13Th: return "minor-13th"; - case KindValue::suspendedSecond: return "suspended-second"; - case KindValue::suspendedFourth: return "suspended-fourth"; - case KindValue::neapolitan: return "Neapolitan"; - case KindValue::italian: return "Italian"; - case KindValue::french: return "French"; - case KindValue::german: return "German"; - case KindValue::pedal: return "pedal"; - case KindValue::power: return "power"; - case KindValue::tristan: return "Tristan"; - case KindValue::other: return "other"; - case KindValue::none: return "none"; - default: break; - } - return "major"; - } - - - std::ostream& toStream( std::ostream& os, const KindValue value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const KindValue value ) - { - return toStream( os, value ); - } - - LineEnd parseLineEnd( const std::string& value ) - { - if ( value == "up" ) { return LineEnd::up; } - else if ( value == "down" ) { return LineEnd::down; } - else if ( value == "both" ) { return LineEnd::both; } - else if ( value == "arrow" ) { return LineEnd::arrow; } - else if ( value == "none" ) { return LineEnd::none; } - return LineEnd::up; - } - - - std::string toString( const LineEnd value ) - { - switch ( value ) - { - case LineEnd::up: return "up"; - case LineEnd::down: return "down"; - case LineEnd::both: return "both"; - case LineEnd::arrow: return "arrow"; - case LineEnd::none: return "none"; - default: break; - } - return "up"; - } - - - std::ostream& toStream( std::ostream& os, const LineEnd value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const LineEnd value ) - { - return toStream( os, value ); - } - - MeasureNumberingValue parseMeasureNumberingValue( const std::string& value ) - { - if ( value == "none" ) { return MeasureNumberingValue::none; } - else if ( value == "measure" ) { return MeasureNumberingValue::measure; } - else if ( value == "system" ) { return MeasureNumberingValue::system; } - return MeasureNumberingValue::none; - } - - - std::string toString( const MeasureNumberingValue value ) - { - switch ( value ) - { - case MeasureNumberingValue::none: return "none"; - case MeasureNumberingValue::measure: return "measure"; - case MeasureNumberingValue::system: return "system"; - default: break; - } - return "none"; - } - - - std::ostream& toStream( std::ostream& os, const MeasureNumberingValue value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const MeasureNumberingValue value ) - { - return toStream( os, value ); - } - - MembraneEnum parseMembraneEnum( const std::string& value ) - { - if ( value == "bass drum" ) { return MembraneEnum::bassDrum; } - else if ( value == "bass drum on side" ) { return MembraneEnum::bassDrumOnSide; } - else if ( value == "bongos" ) { return MembraneEnum::bongos; } - else if ( value == "conga drum" ) { return MembraneEnum::congaDrum; } - else if ( value == "goblet drum" ) { return MembraneEnum::gobletDrum; } - else if ( value == "military drum" ) { return MembraneEnum::militaryDrum; } - else if ( value == "snare drum" ) { return MembraneEnum::snareDrum; } - else if ( value == "snare drum snares off" ) { return MembraneEnum::snareDrumSnaresOff; } - else if ( value == "tambourine" ) { return MembraneEnum::tambourine; } - else if ( value == "tenor drum" ) { return MembraneEnum::tenorDrum; } - else if ( value == "timbales" ) { return MembraneEnum::timbales; } - else if ( value == "tomtom" ) { return MembraneEnum::tomtom; } - return MembraneEnum::bassDrum; - } - - - std::string toString( const MembraneEnum value ) - { - switch ( value ) - { - case MembraneEnum::bassDrum: return "bass drum"; - case MembraneEnum::bassDrumOnSide: return "bass drum on side"; - case MembraneEnum::bongos: return "bongos"; - case MembraneEnum::congaDrum: return "conga drum"; - case MembraneEnum::gobletDrum: return "goblet drum"; - case MembraneEnum::militaryDrum: return "military drum"; - case MembraneEnum::snareDrum: return "snare drum"; - case MembraneEnum::snareDrumSnaresOff: return "snare drum snares off"; - case MembraneEnum::tambourine: return "tambourine"; - case MembraneEnum::tenorDrum: return "tenor drum"; - case MembraneEnum::timbales: return "timbales"; - case MembraneEnum::tomtom: return "tomtom"; - default: break; - } - return "bass drum"; - } - - - std::ostream& toStream( std::ostream& os, const MembraneEnum value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const MembraneEnum value ) - { - return toStream( os, value ); - } - - MetalEnum parseMetalEnum( const std::string& value ) - { - if ( value == "almglocken" ) { return MetalEnum::almglocken; } - else if ( value == "bell" ) { return MetalEnum::bell; } - else if ( value == "bell plate" ) { return MetalEnum::bellPlate; } - else if ( value == "brake drum" ) { return MetalEnum::brakeDrum; } - else if ( value == "Chinese cymbal" ) { return MetalEnum::chineseCymbal; } - else if ( value == "cowbell" ) { return MetalEnum::cowbell; } - else if ( value == "crash cymbals" ) { return MetalEnum::crashCymbals; } - else if ( value == "crotale" ) { return MetalEnum::crotale; } - else if ( value == "cymbal tongs" ) { return MetalEnum::cymbalTongs; } - else if ( value == "domed gong" ) { return MetalEnum::domedGong; } - else if ( value == "finger cymbals" ) { return MetalEnum::fingerCymbals; } - else if ( value == "flexatone" ) { return MetalEnum::flexatone; } - else if ( value == "gong" ) { return MetalEnum::gong; } - else if ( value == "hi-hat" ) { return MetalEnum::hiHat; } - else if ( value == "high-hat cymbals" ) { return MetalEnum::highHatCymbals; } - else if ( value == "handbell" ) { return MetalEnum::handbell; } - else if ( value == "sistrum" ) { return MetalEnum::sistrum; } - else if ( value == "sizzle cymbal" ) { return MetalEnum::sizzleCymbal; } - else if ( value == "sleigh bells" ) { return MetalEnum::sleighBells; } - else if ( value == "suspended cymbal" ) { return MetalEnum::suspendedCymbal; } - else if ( value == "tam tam" ) { return MetalEnum::tamTam; } - else if ( value == "triangle" ) { return MetalEnum::triangle; } - else if ( value == "Vietnamese hat" ) { return MetalEnum::vietnameseHat; } - return MetalEnum::almglocken; - } - - - std::string toString( const MetalEnum value ) - { - switch ( value ) - { - case MetalEnum::almglocken: return "almglocken"; - case MetalEnum::bell: return "bell"; - case MetalEnum::bellPlate: return "bell plate"; - case MetalEnum::brakeDrum: return "brake drum"; - case MetalEnum::chineseCymbal: return "Chinese cymbal"; - case MetalEnum::cowbell: return "cowbell"; - case MetalEnum::crashCymbals: return "crash cymbals"; - case MetalEnum::crotale: return "crotale"; - case MetalEnum::cymbalTongs: return "cymbal tongs"; - case MetalEnum::domedGong: return "domed gong"; - case MetalEnum::fingerCymbals: return "finger cymbals"; - case MetalEnum::flexatone: return "flexatone"; - case MetalEnum::gong: return "gong"; - case MetalEnum::hiHat: return "hi-hat"; - case MetalEnum::highHatCymbals: return "high-hat cymbals"; - case MetalEnum::handbell: return "handbell"; - case MetalEnum::sistrum: return "sistrum"; - case MetalEnum::sizzleCymbal: return "sizzle cymbal"; - case MetalEnum::sleighBells: return "sleigh bells"; - case MetalEnum::suspendedCymbal: return "suspended cymbal"; - case MetalEnum::tamTam: return "tam tam"; - case MetalEnum::triangle: return "triangle"; - case MetalEnum::vietnameseHat: return "Vietnamese hat"; - default: break; - } - return "almglocken"; - } - - - std::ostream& toStream( std::ostream& os, const MetalEnum value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const MetalEnum value ) - { - return toStream( os, value ); - } - - OnOff parseOnOff( const std::string& value ) - { - if ( value == "on" ) { return OnOff::on; } - else if ( value == "off" ) { return OnOff::off; } - return OnOff::on; - } - - - std::string toString( const OnOff value ) - { - switch ( value ) - { - case OnOff::on: return "on"; - case OnOff::off: return "off"; - default: break; - } - return "on"; - } - - - std::ostream& toStream( std::ostream& os, const OnOff value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const OnOff value ) - { - return toStream( os, value ); - } - - PitchedEnum parsePitchedEnum( const std::string& value ) - { - if ( value == "chimes" ) { return PitchedEnum::chimes; } - else if ( value == "glockenspiel" ) { return PitchedEnum::glockenspiel; } - else if ( value == "mallet" ) { return PitchedEnum::mallet; } - else if ( value == "marimba" ) { return PitchedEnum::marimba; } - else if ( value == "tubular chimes" ) { return PitchedEnum::tubularChimes; } - else if ( value == "vibraphone" ) { return PitchedEnum::vibraphone; } - else if ( value == "xylophone" ) { return PitchedEnum::xylophone; } - return PitchedEnum::chimes; - } - - - std::string toString( const PitchedEnum value ) - { - switch ( value ) - { - case PitchedEnum::chimes: return "chimes"; - case PitchedEnum::glockenspiel: return "glockenspiel"; - case PitchedEnum::mallet: return "mallet"; - case PitchedEnum::marimba: return "marimba"; - case PitchedEnum::tubularChimes: return "tubular chimes"; - case PitchedEnum::vibraphone: return "vibraphone"; - case PitchedEnum::xylophone: return "xylophone"; - default: break; - } - return "chimes"; - } - - - std::ostream& toStream( std::ostream& os, const PitchedEnum value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const PitchedEnum value ) - { - return toStream( os, value ); - } - - PrincipalVoiceSymbol parsePrincipalVoiceSymbol( const std::string& value ) - { - if ( value == "Hauptstimme" ) { return PrincipalVoiceSymbol::hauptstimme; } - else if ( value == "Nebenstimme" ) { return PrincipalVoiceSymbol::nebenstimme; } - else if ( value == "plain" ) { return PrincipalVoiceSymbol::plain; } - else if ( value == "none" ) { return PrincipalVoiceSymbol::none; } - return PrincipalVoiceSymbol::hauptstimme; - } - - - std::string toString( const PrincipalVoiceSymbol value ) - { - switch ( value ) - { - case PrincipalVoiceSymbol::hauptstimme: return "Hauptstimme"; - case PrincipalVoiceSymbol::nebenstimme: return "Nebenstimme"; - case PrincipalVoiceSymbol::plain: return "plain"; - case PrincipalVoiceSymbol::none: return "none"; - default: break; - } - return "Hauptstimme"; - } - - - std::ostream& toStream( std::ostream& os, const PrincipalVoiceSymbol value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const PrincipalVoiceSymbol value ) - { - return toStream( os, value ); - } - - StartStopChangeContinue parseStartStopChangeContinue( const std::string& value ) - { - if ( value == "start" ) { return StartStopChangeContinue::start; } - else if ( value == "stop" ) { return StartStopChangeContinue::stop; } - else if ( value == "change" ) { return StartStopChangeContinue::change; } - else if ( value == "continue" ) { return StartStopChangeContinue::continue_; } - return StartStopChangeContinue::start; - } - - - std::string toString( const StartStopChangeContinue value ) - { - switch ( value ) - { - case StartStopChangeContinue::start: return "start"; - case StartStopChangeContinue::stop: return "stop"; - case StartStopChangeContinue::change: return "change"; - case StartStopChangeContinue::continue_: return "continue"; - default: break; - } - return "start"; - } - - - std::ostream& toStream( std::ostream& os, const StartStopChangeContinue value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const StartStopChangeContinue value ) - { - return toStream( os, value ); - } - - TipDirection parseTipDirection( const std::string& value ) - { - if ( value == "up" ) { return TipDirection::up; } - else if ( value == "down" ) { return TipDirection::down; } - else if ( value == "left" ) { return TipDirection::left; } - else if ( value == "right" ) { return TipDirection::right; } - else if ( value == "northwest" ) { return TipDirection::northwest; } - else if ( value == "northeast" ) { return TipDirection::northeast; } - else if ( value == "southeast" ) { return TipDirection::southeast; } - else if ( value == "southwest" ) { return TipDirection::southwest; } - return TipDirection::up; - } - - - std::string toString( const TipDirection value ) - { - switch ( value ) - { - case TipDirection::up: return "up"; - case TipDirection::down: return "down"; - case TipDirection::left: return "left"; - case TipDirection::right: return "right"; - case TipDirection::northwest: return "northwest"; - case TipDirection::northeast: return "northeast"; - case TipDirection::southeast: return "southeast"; - case TipDirection::southwest: return "southwest"; - default: break; - } - return "up"; - } - - - std::ostream& toStream( std::ostream& os, const TipDirection value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const TipDirection value ) - { - return toStream( os, value ); - } - - StickLocationEnum parseStickLocationEnum( const std::string& value ) - { - if ( value == "center" ) { return StickLocationEnum::center; } - else if ( value == "rim" ) { return StickLocationEnum::rim; } - else if ( value == "cymbal bell" ) { return StickLocationEnum::cymbalBell; } - else if ( value == "cymbal edge" ) { return StickLocationEnum::cymbalEdge; } - return StickLocationEnum::center; - } - - - std::string toString( const StickLocationEnum value ) - { - switch ( value ) - { - case StickLocationEnum::center: return "center"; - case StickLocationEnum::rim: return "rim"; - case StickLocationEnum::cymbalBell: return "cymbal bell"; - case StickLocationEnum::cymbalEdge: return "cymbal edge"; - default: break; - } - return "center"; - } - - - std::ostream& toStream( std::ostream& os, const StickLocationEnum value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const StickLocationEnum value ) - { - return toStream( os, value ); - } - - StickMaterialEnum parseStickMaterialEnum( const std::string& value ) - { - if ( value == "soft" ) { return StickMaterialEnum::soft; } - else if ( value == "medium" ) { return StickMaterialEnum::medium; } - else if ( value == "hard" ) { return StickMaterialEnum::hard; } - else if ( value == "shaded" ) { return StickMaterialEnum::shaded; } - else if ( value == "x" ) { return StickMaterialEnum::x; } - return StickMaterialEnum::soft; - } - - - std::string toString( const StickMaterialEnum value ) - { - switch ( value ) - { - case StickMaterialEnum::soft: return "soft"; - case StickMaterialEnum::medium: return "medium"; - case StickMaterialEnum::hard: return "hard"; - case StickMaterialEnum::shaded: return "shaded"; - case StickMaterialEnum::x: return "x"; - default: break; - } - return "soft"; - } - - - std::ostream& toStream( std::ostream& os, const StickMaterialEnum value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const StickMaterialEnum value ) - { - return toStream( os, value ); - } - - StickTypeEnum parseStickTypeEnum( const std::string& value ) - { - if ( value == "bass drum" ) { return StickTypeEnum::bassDrum; } - else if ( value == "double bass drum" ) { return StickTypeEnum::doubleBassDrum; } - else if ( value == "timpani" ) { return StickTypeEnum::timpani; } - else if ( value == "xylophone" ) { return StickTypeEnum::xylophone; } - else if ( value == "yarn" ) { return StickTypeEnum::yarn; } - return StickTypeEnum::bassDrum; - } - - - std::string toString( const StickTypeEnum value ) - { - switch ( value ) - { - case StickTypeEnum::bassDrum: return "bass drum"; - case StickTypeEnum::doubleBassDrum: return "double bass drum"; - case StickTypeEnum::timpani: return "timpani"; - case StickTypeEnum::xylophone: return "xylophone"; - case StickTypeEnum::yarn: return "yarn"; - default: break; - } - return "bass drum"; - } - - - std::ostream& toStream( std::ostream& os, const StickTypeEnum value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const StickTypeEnum value ) - { - return toStream( os, value ); - } - - UpDownStopContinue parseUpDownStopContinue( const std::string& value ) - { - if ( value == "up" ) { return UpDownStopContinue::up; } - else if ( value == "down" ) { return UpDownStopContinue::down; } - else if ( value == "stop" ) { return UpDownStopContinue::stop; } - else if ( value == "continue" ) { return UpDownStopContinue::continue_; } - return UpDownStopContinue::up; - } - - - std::string toString( const UpDownStopContinue value ) - { - switch ( value ) - { - case UpDownStopContinue::up: return "up"; - case UpDownStopContinue::down: return "down"; - case UpDownStopContinue::stop: return "stop"; - case UpDownStopContinue::continue_: return "continue"; - default: break; - } - return "up"; - } - - - std::ostream& toStream( std::ostream& os, const UpDownStopContinue value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const UpDownStopContinue value ) - { - return toStream( os, value ); - } - - WedgeType parseWedgeType( const std::string& value ) - { - if ( value == "crescendo" ) { return WedgeType::crescendo; } - else if ( value == "diminuendo" ) { return WedgeType::diminuendo; } - else if ( value == "stop" ) { return WedgeType::stop; } - else if ( value == "continue" ) { return WedgeType::continue_; } - return WedgeType::crescendo; - } - - - std::string toString( const WedgeType value ) - { - switch ( value ) - { - case WedgeType::crescendo: return "crescendo"; - case WedgeType::diminuendo: return "diminuendo"; - case WedgeType::stop: return "stop"; - case WedgeType::continue_: return "continue"; - default: break; - } - return "crescendo"; - } - - - std::ostream& toStream( std::ostream& os, const WedgeType value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const WedgeType value ) - { - return toStream( os, value ); - } - - WoodEnum parseWoodEnum( const std::string& value ) - { - if ( value == "board clapper" ) { return WoodEnum::boardClapper; } - else if ( value == "cabasa" ) { return WoodEnum::cabasa; } - else if ( value == "castanets" ) { return WoodEnum::castanets; } - else if ( value == "claves" ) { return WoodEnum::claves; } - else if ( value == "guiro" ) { return WoodEnum::guiro; } - else if ( value == "log drum" ) { return WoodEnum::logDrum; } - else if ( value == "maraca" ) { return WoodEnum::maraca; } - else if ( value == "maracas" ) { return WoodEnum::maracas; } - else if ( value == "ratchet" ) { return WoodEnum::ratchet; } - else if ( value == "sandpaper blocks" ) { return WoodEnum::sandpaperBlocks; } - else if ( value == "slit drum" ) { return WoodEnum::slitDrum; } - else if ( value == "temple block" ) { return WoodEnum::templeBlock; } - else if ( value == "vibraslap" ) { return WoodEnum::vibraslap; } - else if ( value == "wood block" ) { return WoodEnum::woodBlock; } - return WoodEnum::boardClapper; - } - - - std::string toString( const WoodEnum value ) - { - switch ( value ) - { - case WoodEnum::boardClapper: return "board clapper"; - case WoodEnum::cabasa: return "cabasa"; - case WoodEnum::castanets: return "castanets"; - case WoodEnum::claves: return "claves"; - case WoodEnum::guiro: return "guiro"; - case WoodEnum::logDrum: return "log drum"; - case WoodEnum::maraca: return "maraca"; - case WoodEnum::maracas: return "maracas"; - case WoodEnum::ratchet: return "ratchet"; - case WoodEnum::sandpaperBlocks: return "sandpaper blocks"; - case WoodEnum::slitDrum: return "slit drum"; - case WoodEnum::templeBlock: return "temple block"; - case WoodEnum::vibraslap: return "vibraslap"; - case WoodEnum::woodBlock: return "wood block"; - default: break; - } - return "board clapper"; - } - - - std::ostream& toStream( std::ostream& os, const WoodEnum value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const WoodEnum value ) - { - return toStream( os, value ); - } - - MarginType parseMarginType( const std::string& value ) - { - if ( value == "odd" ) { return MarginType::odd; } - else if ( value == "even" ) { return MarginType::even; } - else if ( value == "both" ) { return MarginType::both; } - return MarginType::odd; - } - - - std::string toString( const MarginType value ) - { - switch ( value ) - { - case MarginType::odd: return "odd"; - case MarginType::even: return "even"; - case MarginType::both: return "both"; - default: break; - } - return "odd"; - } - - - std::ostream& toStream( std::ostream& os, const MarginType value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const MarginType value ) - { - return toStream( os, value ); - } - - NoteSizeType parseNoteSizeType( const std::string& value ) - { - if ( value == "cue" ) { return NoteSizeType::cue; } - else if ( value == "grace" ) { return NoteSizeType::grace; } - else if ( value == "large" ) { return NoteSizeType::large; } - return NoteSizeType::cue; - } - - - std::string toString( const NoteSizeType value ) - { - switch ( value ) - { - case NoteSizeType::cue: return "cue"; - case NoteSizeType::grace: return "grace"; - case NoteSizeType::large: return "large"; - default: break; - } - return "cue"; - } - - - std::ostream& toStream( std::ostream& os, const NoteSizeType value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const NoteSizeType value ) - { - return toStream( os, value ); - } - - AccidentalValue parseAccidentalValue( const std::string& value ) - { - if ( value == "sharp" ) { return AccidentalValue::sharp; } - else if ( value == "natural" ) { return AccidentalValue::natural; } - else if ( value == "flat" ) { return AccidentalValue::flat; } - else if ( value == "double-sharp" ) { return AccidentalValue::doubleSharp; } - else if ( value == "sharp-sharp" ) { return AccidentalValue::sharpSharp; } - else if ( value == "flat-flat" ) { return AccidentalValue::flatFlat; } - else if ( value == "natural-sharp" ) { return AccidentalValue::naturalSharp; } - else if ( value == "natural-flat" ) { return AccidentalValue::naturalFlat; } - else if ( value == "quarter-flat" ) { return AccidentalValue::quarterFlat; } - else if ( value == "quarter-sharp" ) { return AccidentalValue::quarterSharp; } - else if ( value == "three-quarters-flat" ) { return AccidentalValue::threeQuartersFlat; } - else if ( value == "three-quarters-sharp" ) { return AccidentalValue::threeQuartersSharp; } - else if ( value == "sharp-down" ) { return AccidentalValue::sharpDown; } - else if ( value == "sharp-up" ) { return AccidentalValue::sharpUp; } - else if ( value == "natural-down" ) { return AccidentalValue::naturalDown; } - else if ( value == "natural-up" ) { return AccidentalValue::naturalUp; } - else if ( value == "flat-down" ) { return AccidentalValue::flatDown; } - else if ( value == "flat-up" ) { return AccidentalValue::flatUp; } - else if ( value == "triple-sharp" ) { return AccidentalValue::tripleSharp; } - else if ( value == "triple-flat" ) { return AccidentalValue::tripleFlat; } - else if ( value == "slash-quarter-sharp" ) { return AccidentalValue::slashQuarterSharp; } - else if ( value == "slash-sharp" ) { return AccidentalValue::slashSharp; } - else if ( value == "slash-flat" ) { return AccidentalValue::slashFlat; } - else if ( value == "double-slash-flat" ) { return AccidentalValue::doubleSlashFlat; } - else if ( value == "sharp-1" ) { return AccidentalValue::sharp1; } - else if ( value == "sharp-2" ) { return AccidentalValue::sharp2; } - else if ( value == "sharp-3" ) { return AccidentalValue::sharp3; } - else if ( value == "sharp-5" ) { return AccidentalValue::sharp5; } - else if ( value == "flat-1" ) { return AccidentalValue::flat1; } - else if ( value == "flat-2" ) { return AccidentalValue::flat2; } - else if ( value == "flat-3" ) { return AccidentalValue::flat3; } - else if ( value == "flat-4" ) { return AccidentalValue::flat4; } - else if ( value == "sori" ) { return AccidentalValue::sori; } - else if ( value == "koron" ) { return AccidentalValue::koron; } - return AccidentalValue::sharp; - } - - - std::string toString( const AccidentalValue value ) - { - switch ( value ) - { - case AccidentalValue::sharp: return "sharp"; - case AccidentalValue::natural: return "natural"; - case AccidentalValue::flat: return "flat"; - case AccidentalValue::doubleSharp: return "double-sharp"; - case AccidentalValue::sharpSharp: return "sharp-sharp"; - case AccidentalValue::flatFlat: return "flat-flat"; - case AccidentalValue::naturalSharp: return "natural-sharp"; - case AccidentalValue::naturalFlat: return "natural-flat"; - case AccidentalValue::quarterFlat: return "quarter-flat"; - case AccidentalValue::quarterSharp: return "quarter-sharp"; - case AccidentalValue::threeQuartersFlat: return "three-quarters-flat"; - case AccidentalValue::threeQuartersSharp: return "three-quarters-sharp"; - case AccidentalValue::sharpDown: return "sharp-down"; - case AccidentalValue::sharpUp: return "sharp-up"; - case AccidentalValue::naturalDown: return "natural-down"; - case AccidentalValue::naturalUp: return "natural-up"; - case AccidentalValue::flatDown: return "flat-down"; - case AccidentalValue::flatUp: return "flat-up"; - case AccidentalValue::tripleSharp: return "triple-sharp"; - case AccidentalValue::tripleFlat: return "triple-flat"; - case AccidentalValue::slashQuarterSharp: return "slash-quarter-sharp"; - case AccidentalValue::slashSharp: return "slash-sharp"; - case AccidentalValue::slashFlat: return "slash-flat"; - case AccidentalValue::doubleSlashFlat: return "double-slash-flat"; - case AccidentalValue::sharp1: return "sharp-1"; - case AccidentalValue::sharp2: return "sharp-2"; - case AccidentalValue::sharp3: return "sharp-3"; - case AccidentalValue::sharp5: return "sharp-5"; - case AccidentalValue::flat1: return "flat-1"; - case AccidentalValue::flat2: return "flat-2"; - case AccidentalValue::flat3: return "flat-3"; - case AccidentalValue::flat4: return "flat-4"; - case AccidentalValue::sori: return "sori"; - case AccidentalValue::koron: return "koron"; - default: break; - } - return "sharp"; - } - - - std::ostream& toStream( std::ostream& os, const AccidentalValue value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const AccidentalValue value ) - { - return toStream( os, value ); - } - - ArrowDirectionEnum parseArrowDirectionEnum( const std::string& value ) - { - if ( value == "left" ) { return ArrowDirectionEnum::left; } - else if ( value == "up" ) { return ArrowDirectionEnum::up; } - else if ( value == "right" ) { return ArrowDirectionEnum::right; } - else if ( value == "down" ) { return ArrowDirectionEnum::down; } - else if ( value == "northwest" ) { return ArrowDirectionEnum::northwest; } - else if ( value == "northeast" ) { return ArrowDirectionEnum::northeast; } - else if ( value == "southeast" ) { return ArrowDirectionEnum::southeast; } - else if ( value == "southwest" ) { return ArrowDirectionEnum::southwest; } - else if ( value == "left right" ) { return ArrowDirectionEnum::leftRight; } - else if ( value == "up down" ) { return ArrowDirectionEnum::upDown; } - else if ( value == "northwest southeast" ) { return ArrowDirectionEnum::northwestSoutheast; } - else if ( value == "northeast southwest" ) { return ArrowDirectionEnum::northeastSouthwest; } - else if ( value == "other" ) { return ArrowDirectionEnum::other; } - return ArrowDirectionEnum::left; - } - - - std::string toString( const ArrowDirectionEnum value ) - { - switch ( value ) - { - case ArrowDirectionEnum::left: return "left"; - case ArrowDirectionEnum::up: return "up"; - case ArrowDirectionEnum::right: return "right"; - case ArrowDirectionEnum::down: return "down"; - case ArrowDirectionEnum::northwest: return "northwest"; - case ArrowDirectionEnum::northeast: return "northeast"; - case ArrowDirectionEnum::southeast: return "southeast"; - case ArrowDirectionEnum::southwest: return "southwest"; - case ArrowDirectionEnum::leftRight: return "left right"; - case ArrowDirectionEnum::upDown: return "up down"; - case ArrowDirectionEnum::northwestSoutheast: return "northwest southeast"; - case ArrowDirectionEnum::northeastSouthwest: return "northeast southwest"; - case ArrowDirectionEnum::other: return "other"; - default: break; - } - return "left"; - } - - - std::ostream& toStream( std::ostream& os, const ArrowDirectionEnum value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const ArrowDirectionEnum value ) - { - return toStream( os, value ); - } - - ArrowStyleEnum parseArrowStyleEnum( const std::string& value ) - { - if ( value == "single" ) { return ArrowStyleEnum::single; } - else if ( value == "double" ) { return ArrowStyleEnum::double_; } - else if ( value == "filled" ) { return ArrowStyleEnum::filled; } - else if ( value == "hollow" ) { return ArrowStyleEnum::hollow; } - else if ( value == "paired" ) { return ArrowStyleEnum::paired; } - else if ( value == "combined" ) { return ArrowStyleEnum::combined; } - else if ( value == "other" ) { return ArrowStyleEnum::other; } - return ArrowStyleEnum::single; - } - - - std::string toString( const ArrowStyleEnum value ) - { - switch ( value ) - { - case ArrowStyleEnum::single: return "single"; - case ArrowStyleEnum::double_: return "double"; - case ArrowStyleEnum::filled: return "filled"; - case ArrowStyleEnum::hollow: return "hollow"; - case ArrowStyleEnum::paired: return "paired"; - case ArrowStyleEnum::combined: return "combined"; - case ArrowStyleEnum::other: return "other"; - default: break; - } - return "single"; - } - - - std::ostream& toStream( std::ostream& os, const ArrowStyleEnum value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const ArrowStyleEnum value ) - { - return toStream( os, value ); - } - - BeamValue parseBeamValue( const std::string& value ) - { - if ( value == "begin" ) { return BeamValue::begin; } - else if ( value == "continue" ) { return BeamValue::continue_; } - else if ( value == "end" ) { return BeamValue::end; } - else if ( value == "forward hook" ) { return BeamValue::forwardHook; } - else if ( value == "backward hook" ) { return BeamValue::backwardHook; } - return BeamValue::begin; - } - - - std::string toString( const BeamValue value ) - { - switch ( value ) - { - case BeamValue::begin: return "begin"; - case BeamValue::continue_: return "continue"; - case BeamValue::end: return "end"; - case BeamValue::forwardHook: return "forward hook"; - case BeamValue::backwardHook: return "backward hook"; - default: break; - } - return "begin"; - } - - - std::ostream& toStream( std::ostream& os, const BeamValue value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const BeamValue value ) - { - return toStream( os, value ); - } - - BreathMarkValue parseBreathMarkValue( const std::string& value ) - { - if ( value == "" ) { return BreathMarkValue::emptystring; } - else if ( value == "comma" ) { return BreathMarkValue::comma; } - else if ( value == "tick" ) { return BreathMarkValue::tick; } - return BreathMarkValue::emptystring; - } - - - std::string toString( const BreathMarkValue value ) - { - switch ( value ) - { - case BreathMarkValue::emptystring: return ""; - case BreathMarkValue::comma: return "comma"; - case BreathMarkValue::tick: return "tick"; - default: break; - } - return ""; - } - - - std::ostream& toStream( std::ostream& os, const BreathMarkValue value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const BreathMarkValue value ) - { - return toStream( os, value ); - } - - CircularArrowEnum parseCircularArrowEnum( const std::string& value ) - { - if ( value == "clockwise" ) { return CircularArrowEnum::clockwise; } - else if ( value == "anticlockwise" ) { return CircularArrowEnum::anticlockwise; } - return CircularArrowEnum::clockwise; - } - - - std::string toString( const CircularArrowEnum value ) - { - switch ( value ) - { - case CircularArrowEnum::clockwise: return "clockwise"; - case CircularArrowEnum::anticlockwise: return "anticlockwise"; - default: break; - } - return "clockwise"; - } - - - std::ostream& toStream( std::ostream& os, const CircularArrowEnum value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const CircularArrowEnum value ) - { - return toStream( os, value ); - } - - Fan parseFan( const std::string& value ) - { - if ( value == "accel" ) { return Fan::accel; } - else if ( value == "rit" ) { return Fan::rit; } - else if ( value == "none" ) { return Fan::none; } - return Fan::accel; - } - - - std::string toString( const Fan value ) - { - switch ( value ) - { - case Fan::accel: return "accel"; - case Fan::rit: return "rit"; - case Fan::none: return "none"; - default: break; - } - return "accel"; - } - - - std::ostream& toStream( std::ostream& os, const Fan value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const Fan value ) - { - return toStream( os, value ); - } - - HandbellValue parseHandbellValue( const std::string& value ) - { - if ( value == "damp" ) { return HandbellValue::damp; } - else if ( value == "echo" ) { return HandbellValue::echo; } - else if ( value == "gyro" ) { return HandbellValue::gyro; } - else if ( value == "hand martellato" ) { return HandbellValue::handMartellato; } - else if ( value == "mallet lift" ) { return HandbellValue::malletLift; } - else if ( value == "mallet table" ) { return HandbellValue::malletTable; } - else if ( value == "martellato" ) { return HandbellValue::martellato; } - else if ( value == "martellato lift" ) { return HandbellValue::martellatoLift; } - else if ( value == "muted martellato" ) { return HandbellValue::mutedMartellato; } - else if ( value == "pluck lift" ) { return HandbellValue::pluckLift; } - else if ( value == "swing" ) { return HandbellValue::swing; } - return HandbellValue::damp; - } - - - std::string toString( const HandbellValue value ) - { - switch ( value ) - { - case HandbellValue::damp: return "damp"; - case HandbellValue::echo: return "echo"; - case HandbellValue::gyro: return "gyro"; - case HandbellValue::handMartellato: return "hand martellato"; - case HandbellValue::malletLift: return "mallet lift"; - case HandbellValue::malletTable: return "mallet table"; - case HandbellValue::martellato: return "martellato"; - case HandbellValue::martellatoLift: return "martellato lift"; - case HandbellValue::mutedMartellato: return "muted martellato"; - case HandbellValue::pluckLift: return "pluck lift"; - case HandbellValue::swing: return "swing"; - default: break; - } - return "damp"; - } - - - std::ostream& toStream( std::ostream& os, const HandbellValue value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const HandbellValue value ) - { - return toStream( os, value ); - } - - HoleClosedLocation parseHoleClosedLocation( const std::string& value ) - { - if ( value == "right" ) { return HoleClosedLocation::right; } - else if ( value == "bottom" ) { return HoleClosedLocation::bottom; } - else if ( value == "left" ) { return HoleClosedLocation::left; } - else if ( value == "top" ) { return HoleClosedLocation::top; } - return HoleClosedLocation::right; - } - - - std::string toString( const HoleClosedLocation value ) - { - switch ( value ) - { - case HoleClosedLocation::right: return "right"; - case HoleClosedLocation::bottom: return "bottom"; - case HoleClosedLocation::left: return "left"; - case HoleClosedLocation::top: return "top"; - default: break; - } - return "right"; - } - - - std::ostream& toStream( std::ostream& os, const HoleClosedLocation value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const HoleClosedLocation value ) - { - return toStream( os, value ); - } - - HoleClosedValue parseHoleClosedValue( const std::string& value ) - { - if ( value == "yes" ) { return HoleClosedValue::yes; } - else if ( value == "no" ) { return HoleClosedValue::no; } - else if ( value == "half" ) { return HoleClosedValue::half; } - return HoleClosedValue::yes; - } - - - std::string toString( const HoleClosedValue value ) - { - switch ( value ) - { - case HoleClosedValue::yes: return "yes"; - case HoleClosedValue::no: return "no"; - case HoleClosedValue::half: return "half"; - default: break; - } - return "yes"; - } - - - std::ostream& toStream( std::ostream& os, const HoleClosedValue value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const HoleClosedValue value ) - { - return toStream( os, value ); - } - - NoteTypeValue parseNoteTypeValue( const std::string& value ) - { - if ( value == "1024th" ) { return NoteTypeValue::oneThousandTwentyFourth; } - else if ( value == "512th" ) { return NoteTypeValue::fiveHundredTwelfth; } - else if ( value == "256th" ) { return NoteTypeValue::twoHundredFifthySixth; } - else if ( value == "128th" ) { return NoteTypeValue::oneHundredTwentyEighth; } - else if ( value == "64th" ) { return NoteTypeValue::sixtyFourth; } - else if ( value == "32nd" ) { return NoteTypeValue::thirtySecond; } - else if ( value == "16th" ) { return NoteTypeValue::sixteenth; } - else if ( value == "eighth" ) { return NoteTypeValue::eighth; } - else if ( value == "quarter" ) { return NoteTypeValue::quarter; } - else if ( value == "half" ) { return NoteTypeValue::half; } - else if ( value == "whole" ) { return NoteTypeValue::whole; } - else if ( value == "breve" ) { return NoteTypeValue::breve; } - else if ( value == "long" ) { return NoteTypeValue::long_; } - else if ( value == "maxima" ) { return NoteTypeValue::maxima; } - return NoteTypeValue::oneThousandTwentyFourth; - } - - - std::string toString( const NoteTypeValue value ) - { - switch ( value ) - { - case NoteTypeValue::oneThousandTwentyFourth: return "1024th"; - case NoteTypeValue::fiveHundredTwelfth: return "512th"; - case NoteTypeValue::twoHundredFifthySixth: return "256th"; - case NoteTypeValue::oneHundredTwentyEighth: return "128th"; - case NoteTypeValue::sixtyFourth: return "64th"; - case NoteTypeValue::thirtySecond: return "32nd"; - case NoteTypeValue::sixteenth: return "16th"; - case NoteTypeValue::eighth: return "eighth"; - case NoteTypeValue::quarter: return "quarter"; - case NoteTypeValue::half: return "half"; - case NoteTypeValue::whole: return "whole"; - case NoteTypeValue::breve: return "breve"; - case NoteTypeValue::long_: return "long"; - case NoteTypeValue::maxima: return "maxima"; - default: break; - } - return "1024th"; - } - - - std::ostream& toStream( std::ostream& os, const NoteTypeValue value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const NoteTypeValue value ) - { - return toStream( os, value ); - } - - NoteheadValue parseNoteheadValue( const std::string& value ) - { - if ( value == "slash" ) { return NoteheadValue::slash; } - else if ( value == "triangle" ) { return NoteheadValue::triangle; } - else if ( value == "diamond" ) { return NoteheadValue::diamond; } - else if ( value == "square" ) { return NoteheadValue::square; } - else if ( value == "cross" ) { return NoteheadValue::cross; } - else if ( value == "x" ) { return NoteheadValue::x; } - else if ( value == "circle-x" ) { return NoteheadValue::circleX; } - else if ( value == "inverted triangle" ) { return NoteheadValue::invertedTriangle; } - else if ( value == "arrow down" ) { return NoteheadValue::arrowDown; } - else if ( value == "arrow up" ) { return NoteheadValue::arrowUp; } - else if ( value == "slashed" ) { return NoteheadValue::slashed; } - else if ( value == "back slashed" ) { return NoteheadValue::backSlashed; } - else if ( value == "normal" ) { return NoteheadValue::normal; } - else if ( value == "cluster" ) { return NoteheadValue::cluster; } - else if ( value == "circle dot" ) { return NoteheadValue::circleDot; } - else if ( value == "left triangle" ) { return NoteheadValue::leftTriangle; } - else if ( value == "rectangle" ) { return NoteheadValue::rectangle; } - else if ( value == "none" ) { return NoteheadValue::none; } - else if ( value == "do" ) { return NoteheadValue::do_; } - else if ( value == "re" ) { return NoteheadValue::re; } - else if ( value == "mi" ) { return NoteheadValue::mi; } - else if ( value == "fa" ) { return NoteheadValue::fa; } - else if ( value == "fa up" ) { return NoteheadValue::faUp; } - else if ( value == "so" ) { return NoteheadValue::so; } - else if ( value == "la" ) { return NoteheadValue::la; } - else if ( value == "ti" ) { return NoteheadValue::ti; } - return NoteheadValue::slash; - } - - - std::string toString( const NoteheadValue value ) - { - switch ( value ) - { - case NoteheadValue::slash: return "slash"; - case NoteheadValue::triangle: return "triangle"; - case NoteheadValue::diamond: return "diamond"; - case NoteheadValue::square: return "square"; - case NoteheadValue::cross: return "cross"; - case NoteheadValue::x: return "x"; - case NoteheadValue::circleX: return "circle-x"; - case NoteheadValue::invertedTriangle: return "inverted triangle"; - case NoteheadValue::arrowDown: return "arrow down"; - case NoteheadValue::arrowUp: return "arrow up"; - case NoteheadValue::slashed: return "slashed"; - case NoteheadValue::backSlashed: return "back slashed"; - case NoteheadValue::normal: return "normal"; - case NoteheadValue::cluster: return "cluster"; - case NoteheadValue::circleDot: return "circle dot"; - case NoteheadValue::leftTriangle: return "left triangle"; - case NoteheadValue::rectangle: return "rectangle"; - case NoteheadValue::none: return "none"; - case NoteheadValue::do_: return "do"; - case NoteheadValue::re: return "re"; - case NoteheadValue::mi: return "mi"; - case NoteheadValue::fa: return "fa"; - case NoteheadValue::faUp: return "fa up"; - case NoteheadValue::so: return "so"; - case NoteheadValue::la: return "la"; - case NoteheadValue::ti: return "ti"; - default: break; - } - return "slash"; - } - - - std::ostream& toStream( std::ostream& os, const NoteheadValue value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const NoteheadValue value ) - { - return toStream( os, value ); - } - - ShowTuplet parseShowTuplet( const std::string& value ) - { - if ( value == "actual" ) { return ShowTuplet::actual; } - else if ( value == "both" ) { return ShowTuplet::both; } - else if ( value == "none" ) { return ShowTuplet::none; } - return ShowTuplet::actual; - } - - - std::string toString( const ShowTuplet value ) - { - switch ( value ) - { - case ShowTuplet::actual: return "actual"; - case ShowTuplet::both: return "both"; - case ShowTuplet::none: return "none"; - default: break; - } - return "actual"; - } - - - std::ostream& toStream( std::ostream& os, const ShowTuplet value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const ShowTuplet value ) - { - return toStream( os, value ); - } - - StemValue parseStemValue( const std::string& value ) - { - if ( value == "down" ) { return StemValue::down; } - else if ( value == "up" ) { return StemValue::up; } - else if ( value == "double" ) { return StemValue::double_; } - else if ( value == "none" ) { return StemValue::none; } - return StemValue::down; - } - - - std::string toString( const StemValue value ) - { - switch ( value ) - { - case StemValue::down: return "down"; - case StemValue::up: return "up"; - case StemValue::double_: return "double"; - case StemValue::none: return "none"; - default: break; - } - return "down"; - } - - - std::ostream& toStream( std::ostream& os, const StemValue value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const StemValue value ) - { - return toStream( os, value ); - } - - StepEnum parseStepEnum( const std::string& value ) - { - if ( value == "A" ) { return StepEnum::a; } - else if ( value == "B" ) { return StepEnum::b; } - else if ( value == "C" ) { return StepEnum::c; } - else if ( value == "D" ) { return StepEnum::d; } - else if ( value == "E" ) { return StepEnum::e; } - else if ( value == "F" ) { return StepEnum::f; } - else if ( value == "G" ) { return StepEnum::g; } - return StepEnum::a; - } - - - std::string toString( const StepEnum value ) - { - switch ( value ) - { - case StepEnum::a: return "A"; - case StepEnum::b: return "B"; - case StepEnum::c: return "C"; - case StepEnum::d: return "D"; - case StepEnum::e: return "E"; - case StepEnum::f: return "F"; - case StepEnum::g: return "G"; - default: break; - } - return "A"; - } - - - std::ostream& toStream( std::ostream& os, const StepEnum value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const StepEnum value ) - { - return toStream( os, value ); - } - - SyllabicEnum parseSyllabicEnum( const std::string& value ) - { - if ( value == "single" ) { return SyllabicEnum::single; } - else if ( value == "begin" ) { return SyllabicEnum::begin; } - else if ( value == "end" ) { return SyllabicEnum::end; } - else if ( value == "middle" ) { return SyllabicEnum::middle; } - return SyllabicEnum::single; - } - - - std::string toString( const SyllabicEnum value ) - { - switch ( value ) - { - case SyllabicEnum::single: return "single"; - case SyllabicEnum::begin: return "begin"; - case SyllabicEnum::end: return "end"; - case SyllabicEnum::middle: return "middle"; - default: break; - } - return "single"; - } - - - std::ostream& toStream( std::ostream& os, const SyllabicEnum value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const SyllabicEnum value ) - { - return toStream( os, value ); - } - - GroupBarlineValue parseGroupBarlineValue( const std::string& value ) - { - if ( value == "yes" ) { return GroupBarlineValue::yes; } - else if ( value == "no" ) { return GroupBarlineValue::no; } - else if ( value == "Mensurstrich" ) { return GroupBarlineValue::mensurstrich; } - return GroupBarlineValue::yes; - } - - - std::string toString( const GroupBarlineValue value ) - { - switch ( value ) - { - case GroupBarlineValue::yes: return "yes"; - case GroupBarlineValue::no: return "no"; - case GroupBarlineValue::mensurstrich: return "Mensurstrich"; - default: break; - } - return "yes"; - } - - - std::ostream& toStream( std::ostream& os, const GroupBarlineValue value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const GroupBarlineValue value ) - { - return toStream( os, value ); - } - - GroupSymbolValue parseGroupSymbolValue( const std::string& value ) - { - if ( value == "none" ) { return GroupSymbolValue::none; } - else if ( value == "brace" ) { return GroupSymbolValue::brace; } - else if ( value == "line" ) { return GroupSymbolValue::line; } - else if ( value == "bracket" ) { return GroupSymbolValue::bracket; } - else if ( value == "square" ) { return GroupSymbolValue::square; } - return GroupSymbolValue::none; - } - - - std::string toString( const GroupSymbolValue value ) - { - switch ( value ) - { - case GroupSymbolValue::none: return "none"; - case GroupSymbolValue::brace: return "brace"; - case GroupSymbolValue::line: return "line"; - case GroupSymbolValue::bracket: return "bracket"; - case GroupSymbolValue::square: return "square"; - default: break; - } - return "none"; - } - - - std::ostream& toStream( std::ostream& os, const GroupSymbolValue value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const GroupSymbolValue value ) - { - return toStream( os, value ); - } - - ModeEnum parseModeEnum( const std::string& value, bool& success ) - { - success = true; - if ( value == "major" ) { return ModeEnum::major; } - else if ( value == "minor" ) { return ModeEnum::minor; } - else if ( value == "dorian" ) { return ModeEnum::dorian; } - else if ( value == "phrygian" ) { return ModeEnum::phrygian; } - else if ( value == "lydian" ) { return ModeEnum::lydian; } - else if ( value == "mixolydian" ) { return ModeEnum::mixolydian; } - else if ( value == "aeolian" ) { return ModeEnum::aeolian; } - else if ( value == "ionian" ) { return ModeEnum::ionian; } - else if ( value == "locrian" ) { return ModeEnum::locrian; } - else if ( value == "none" ) { return ModeEnum::none; } - else if ( value == "other" ) { success = false; return ModeEnum::other; } - success = false; - return ModeEnum::other; - } - ModeEnum parseModeEnum( const std::string& value ) - { - bool temp; - return parseModeEnum( value, temp ); - } - - - std::string toString( const ModeEnum value ) - { - switch ( value ) - { - case ModeEnum::major: return "major"; - case ModeEnum::minor: return "minor"; - case ModeEnum::dorian: return "dorian"; - case ModeEnum::phrygian: return "phrygian"; - case ModeEnum::lydian: return "lydian"; - case ModeEnum::mixolydian: return "mixolydian"; - case ModeEnum::aeolian: return "aeolian"; - case ModeEnum::ionian: return "ionian"; - case ModeEnum::locrian: return "locrian"; - case ModeEnum::none: return "none"; - case ModeEnum::other: return "other"; - default: break; - } - return "other"; - } - - - std::ostream& toStream( std::ostream& os, const ModeEnum value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const ModeEnum value ) - { - return toStream( os, value ); - } - - ModeValue::ModeValue( const ModeEnum value ) - :myEnum( value ) - ,myCustomValue( "" ) - { - setValue( value ); - } - ModeValue::ModeValue( const std::string& value ) - :myEnum( ModeEnum::other ) - ,myCustomValue( value ) - { - setValue( value ); - } - ModeValue::ModeValue() - :myEnum( ModeEnum::major ) - ,myCustomValue( "" ) - { - setValue( ModeEnum::major ); - } - ModeEnum ModeValue::getValue() const - { - return myEnum; - } - - - std::string ModeValue::getValueString() const - { - if ( myEnum != ModeEnum::other ) - { - return toString( myEnum ); - } - else - { - return myCustomValue; - } - } - void ModeValue::setValue( const ModeEnum value ) - { - myEnum = value; - } - void ModeValue::setValue( const std::string& value ) - { - bool found = false; - ModeEnum temp = parseModeEnum( value, found ); - if ( found ) - { - myEnum = temp; - } - else - { - setValue( ModeEnum::other ); - myCustomValue = value; - } - } - ModeValue parseModeValue( const std::string& value ) - { - return ModeValue( value ); - } - - - std::string toString( const ModeValue& value ) - { - return value.getValueString(); - } - - - std::ostream& toStream( std::ostream& os, const ModeValue& value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const ModeValue& value ) - { - return toStream( os, value ); - } - - DistanceTypeEnum parseDistanceTypeEnum( const std::string& value, bool& success ) - { - success = true; - if ( value == "beam" ) { return DistanceTypeEnum::beam; } - else if ( value == "hyphen" ) { return DistanceTypeEnum::hyphen; } - else if ( value == "other" ) { success = false; return DistanceTypeEnum::other; } - success = false; - return DistanceTypeEnum::other; - } - DistanceTypeEnum parseDistanceTypeEnum( const std::string& value ) - { - bool temp; - return parseDistanceTypeEnum( value, temp ); - } - - - std::string toString( const DistanceTypeEnum value ) - { - switch ( value ) - { - case DistanceTypeEnum::beam: return "beam"; - case DistanceTypeEnum::hyphen: return "hyphen"; - case DistanceTypeEnum::other: return "other"; - default: break; - } - return "other"; - } - - - std::ostream& toStream( std::ostream& os, const DistanceTypeEnum value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const DistanceTypeEnum value ) - { - return toStream( os, value ); - } - - DistanceType::DistanceType( const DistanceTypeEnum value ) - :myEnum( value ) - ,myCustomValue( "" ) - { - setValue( value ); - } - DistanceType::DistanceType( const std::string& value ) - :myEnum( DistanceTypeEnum::other ) - ,myCustomValue( value ) - { - setValue( value ); - } - DistanceType::DistanceType() - :myEnum( DistanceTypeEnum::beam ) - ,myCustomValue( "" ) - { - setValue( DistanceTypeEnum::beam ); - } - DistanceTypeEnum DistanceType::getValue() const - { - return myEnum; - } - - - std::string DistanceType::getValueString() const - { - if ( myEnum != DistanceTypeEnum::other ) - { - return toString( myEnum ); - } - else - { - return myCustomValue; - } - } - void DistanceType::setValue( const DistanceTypeEnum value ) - { - myEnum = value; - } - void DistanceType::setValue( const std::string& value ) - { - bool found = false; - DistanceTypeEnum temp = parseDistanceTypeEnum( value, found ); - if ( found ) - { - myEnum = temp; - } - else - { - setValue( DistanceTypeEnum::other ); - myCustomValue = value; - } - } - DistanceType parseDistanceType( const std::string& value ) - { - return DistanceType( value ); - } - - - std::string toString( const DistanceType& value ) - { - return value.getValueString(); - } - - - std::ostream& toStream( std::ostream& os, const DistanceType& value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const DistanceType& value ) - { - return toStream( os, value ); - } - - LineWidthTypeEnum parseLineWidthTypeEnum( const std::string& value, bool& success ) - { - success = true; - if ( value == "beam" ) { return LineWidthTypeEnum::beam; } - else if ( value == "bracket" ) { return LineWidthTypeEnum::bracket; } - else if ( value == "dashes" ) { return LineWidthTypeEnum::dashes; } - else if ( value == "enclosure" ) { return LineWidthTypeEnum::enclosure; } - else if ( value == "ending" ) { return LineWidthTypeEnum::ending; } - else if ( value == "extend" ) { return LineWidthTypeEnum::extend; } - else if ( value == "heavy barline" ) { return LineWidthTypeEnum::heavyBarline; } - else if ( value == "leger" ) { return LineWidthTypeEnum::leger; } - else if ( value == "light barline" ) { return LineWidthTypeEnum::lightBarline; } - else if ( value == "octave shift" ) { return LineWidthTypeEnum::octaveShift; } - else if ( value == "pedal" ) { return LineWidthTypeEnum::pedal; } - else if ( value == "slur middle" ) { return LineWidthTypeEnum::slurMiddle; } - else if ( value == "slur tip" ) { return LineWidthTypeEnum::slurTip; } - else if ( value == "staff" ) { return LineWidthTypeEnum::staff; } - else if ( value == "stem" ) { return LineWidthTypeEnum::stem; } - else if ( value == "tie middle" ) { return LineWidthTypeEnum::tieMiddle; } - else if ( value == "tie tip" ) { return LineWidthTypeEnum::tieTip; } - else if ( value == "tuplet bracket" ) { return LineWidthTypeEnum::tupletBracket; } - else if ( value == "wedge" ) { return LineWidthTypeEnum::wedge; } - else if ( value == "other" ) { success = false; return LineWidthTypeEnum::other; } - success = false; - return LineWidthTypeEnum::other; - } - LineWidthTypeEnum parseLineWidthTypeEnum( const std::string& value ) - { - bool temp; - return parseLineWidthTypeEnum( value, temp ); - } - - - std::string toString( const LineWidthTypeEnum value ) - { - switch ( value ) - { - case LineWidthTypeEnum::beam: return "beam"; - case LineWidthTypeEnum::bracket: return "bracket"; - case LineWidthTypeEnum::dashes: return "dashes"; - case LineWidthTypeEnum::enclosure: return "enclosure"; - case LineWidthTypeEnum::ending: return "ending"; - case LineWidthTypeEnum::extend: return "extend"; - case LineWidthTypeEnum::heavyBarline: return "heavy barline"; - case LineWidthTypeEnum::leger: return "leger"; - case LineWidthTypeEnum::lightBarline: return "light barline"; - case LineWidthTypeEnum::octaveShift: return "octave shift"; - case LineWidthTypeEnum::pedal: return "pedal"; - case LineWidthTypeEnum::slurMiddle: return "slur middle"; - case LineWidthTypeEnum::slurTip: return "slur tip"; - case LineWidthTypeEnum::staff: return "staff"; - case LineWidthTypeEnum::stem: return "stem"; - case LineWidthTypeEnum::tieMiddle: return "tie middle"; - case LineWidthTypeEnum::tieTip: return "tie tip"; - case LineWidthTypeEnum::tupletBracket: return "tuplet bracket"; - case LineWidthTypeEnum::wedge: return "wedge"; - case LineWidthTypeEnum::other: return "other"; - default: break; - } - return "other"; - } - - - std::ostream& toStream( std::ostream& os, const LineWidthTypeEnum value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const LineWidthTypeEnum value ) - { - return toStream( os, value ); - } - - LineWidthType::LineWidthType( const LineWidthTypeEnum value ) - :myEnum( value ) - ,myCustomValue( "" ) - { - setValue( value ); - } - LineWidthType::LineWidthType( const std::string& value ) - :myEnum( LineWidthTypeEnum::other ) - ,myCustomValue( value ) - { - setValue( value ); - } - LineWidthType::LineWidthType() - :myEnum( LineWidthTypeEnum::beam ) - ,myCustomValue( "" ) - { - setValue( LineWidthTypeEnum::beam ); - } - LineWidthTypeEnum LineWidthType::getValue() const - { - return myEnum; - } - - - std::string LineWidthType::getValueString() const - { - if ( myEnum != LineWidthTypeEnum::other ) - { - return toString( myEnum ); - } - else - { - return myCustomValue; - } - } - void LineWidthType::setValue( const LineWidthTypeEnum value ) - { - myEnum = value; - } - void LineWidthType::setValue( const std::string& value ) - { - bool found = false; - LineWidthTypeEnum temp = parseLineWidthTypeEnum( value, found ); - if ( found ) - { - myEnum = temp; - } - else - { - setValue( LineWidthTypeEnum::other ); - myCustomValue = value; - } - } - LineWidthType parseLineWidthType( const std::string& value ) - { - return LineWidthType( value ); - } - - - std::string toString( const LineWidthType& value ) - { - return value.getValueString(); - } - - - std::ostream& toStream( std::ostream& os, const LineWidthType& value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const LineWidthType& value ) - { - return toStream( os, value ); - } - - XlinkActuate parseXlinkActuate( const std::string& value ) - { - if ( value == "onLoad" ) { return XlinkActuate::onLoad; } - else if ( value == "onRequest" ) { return XlinkActuate::onRequest; } - else if ( value == "other" ) { return XlinkActuate::other; } - else if ( value == "none" ) { return XlinkActuate::none; } - return XlinkActuate::onLoad; - } - - - std::string toString( const XlinkActuate value ) - { - switch ( value ) - { - case XlinkActuate::onLoad: return "onLoad"; - case XlinkActuate::onRequest: return "onRequest"; - case XlinkActuate::other: return "other"; - case XlinkActuate::none: return "none"; - default: break; - } - return "none"; - } - - - std::ostream& toStream( std::ostream& os, const XlinkActuate value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const XlinkActuate value ) - { - return toStream( os, value ); - } - - XlinkShow parseXlinkShow( const std::string& value ) - { - if ( value == "new" ) { return XlinkShow::new_; } - else if ( value == "replace" ) { return XlinkShow::replace; } - else if ( value == "embed" ) { return XlinkShow::embed; } - else if ( value == "other" ) { return XlinkShow::other; } - else if ( value == "none" ) { return XlinkShow::none; } - return XlinkShow::new_; - } - - - std::string toString( const XlinkShow value ) - { - switch ( value ) - { - case XlinkShow::new_: return "new"; - case XlinkShow::replace: return "replace"; - case XlinkShow::embed: return "embed"; - case XlinkShow::other: return "other"; - case XlinkShow::none: return "none"; - default: break; - } - return "none"; - } - - - std::ostream& toStream( std::ostream& os, const XlinkShow value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const XlinkShow value ) - { - return toStream( os, value ); - } - - XlinkType parseXlinkType( const std::string& value ) - { - if ( value == "simple" ) { return XlinkType::simple; } - else if ( value == "extended" ) { return XlinkType::extended; } - else if ( value == "title" ) { return XlinkType::title; } - else if ( value == "resource" ) { return XlinkType::resource; } - else if ( value == "locator" ) { return XlinkType::locator; } - else if ( value == "arc" ) { return XlinkType::arc; } - return XlinkType::simple; - } - - - std::string toString( const XlinkType value ) - { - switch ( value ) - { - case XlinkType::simple: return "simple"; - case XlinkType::extended: return "extended"; - case XlinkType::title: return "title"; - case XlinkType::resource: return "resource"; - case XlinkType::locator: return "locator"; - case XlinkType::arc: return "arc"; - default: break; - } - return "simple"; - } - - - std::ostream& toStream( std::ostream& os, const XlinkType value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const XlinkType value ) - { - return toStream( os, value ); - } - - XmlSpace parseXmlSpace( const std::string& value ) - { - if ( value == "default" ) { return XmlSpace::default_; } - else if ( value == "preserve" ) { return XmlSpace::preserve; } - return XmlSpace::default_; - } - - - std::string toString( const XmlSpace value ) - { - switch ( value ) - { - case XmlSpace::default_: return "default"; - case XmlSpace::preserve: return "preserve"; - default: break; - } - return "default"; - } - - - std::ostream& toStream( std::ostream& os, const XmlSpace value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const XmlSpace value ) - { - return toStream( os, value ); - } - - DynamicsEnum parseDynamicsEnum( const std::string& value, bool& success ) - { - success = true; - if ( value == "p" ) { return DynamicsEnum::p; } - else if ( value == "pp" ) { return DynamicsEnum::pp; } - else if ( value == "ppp" ) { return DynamicsEnum::ppp; } - else if ( value == "pppp" ) { return DynamicsEnum::pppp; } - else if ( value == "ppppp" ) { return DynamicsEnum::ppppp; } - else if ( value == "pppppp" ) { return DynamicsEnum::pppppp; } - else if ( value == "f" ) { return DynamicsEnum::f; } - else if ( value == "ff" ) { return DynamicsEnum::ff; } - else if ( value == "fff" ) { return DynamicsEnum::fff; } - else if ( value == "ffff" ) { return DynamicsEnum::ffff; } - else if ( value == "fffff" ) { return DynamicsEnum::fffff; } - else if ( value == "ffffff" ) { return DynamicsEnum::ffffff; } - else if ( value == "mp" ) { return DynamicsEnum::mp; } - else if ( value == "mf" ) { return DynamicsEnum::mf; } - else if ( value == "sf" ) { return DynamicsEnum::sf; } - else if ( value == "sfp" ) { return DynamicsEnum::sfp; } - else if ( value == "sfpp" ) { return DynamicsEnum::sfpp; } - else if ( value == "fp" ) { return DynamicsEnum::fp; } - else if ( value == "rf" ) { return DynamicsEnum::rf; } - else if ( value == "rfz" ) { return DynamicsEnum::rfz; } - else if ( value == "sfz" ) { return DynamicsEnum::sfz; } - else if ( value == "sffz" ) { return DynamicsEnum::sffz; } - else if ( value == "fz" ) { return DynamicsEnum::fz; } - else if ( value == "other-dynamics" ) { return DynamicsEnum::otherDynamics; } - success = false; - return DynamicsEnum::otherDynamics; - } - DynamicsEnum parseDynamicsEnum( const std::string& value ) - { - bool success = true; - return parseDynamicsEnum( value, success ); - } - - - std::string toString( const DynamicsEnum value ) - { - switch ( value ) - { - case DynamicsEnum::p: { return "p"; } - case DynamicsEnum::pp: { return "pp"; } - case DynamicsEnum::ppp: { return "ppp"; } - case DynamicsEnum::pppp: { return "pppp"; } - case DynamicsEnum::ppppp: { return "ppppp"; } - case DynamicsEnum::pppppp: { return "pppppp"; } - case DynamicsEnum::f: { return "f"; } - case DynamicsEnum::ff: { return "ff"; } - case DynamicsEnum::fff: { return "fff"; } - case DynamicsEnum::ffff: { return "ffff"; } - case DynamicsEnum::fffff: { return "fffff"; } - case DynamicsEnum::ffffff: { return "ffffff"; } - case DynamicsEnum::mp: { return "mp"; } - case DynamicsEnum::mf: { return "mf"; } - case DynamicsEnum::sf: { return "sf"; } - case DynamicsEnum::sfp: { return "sfp"; } - case DynamicsEnum::sfpp: { return "sfpp"; } - case DynamicsEnum::fp: { return "fp"; } - case DynamicsEnum::rf: { return "rf"; } - case DynamicsEnum::rfz: { return "rfz"; } - case DynamicsEnum::sfz: { return "sfz"; } - case DynamicsEnum::sffz: { return "sffz"; } - case DynamicsEnum::fz: { return "fz"; } - case DynamicsEnum::otherDynamics: { return "other-dynamics"; } - default: break; - } - return "default"; - } - - - std::ostream& toStream( std::ostream& os, const DynamicsEnum value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const DynamicsEnum value ) - { - return toStream( os, value ); - } - - DynamicsValue::DynamicsValue( const DynamicsEnum value ) - :myEnum( value ) - ,myCustomValue( "" ) - { - setValue( value ); - } - DynamicsValue::DynamicsValue( const std::string& value ) - :myEnum( DynamicsEnum::otherDynamics ) - ,myCustomValue( value ) - { - setValue( value ); - } - DynamicsValue::DynamicsValue() - :myEnum( DynamicsEnum::mf ) - ,myCustomValue( "" ) - { - setValue( DynamicsEnum::mf ); - } - DynamicsEnum DynamicsValue::getValue() const - { - return myEnum; - } - - - std::string DynamicsValue::getValueString() const - { - if ( myEnum != DynamicsEnum::otherDynamics ) - { - return toString( myEnum ); - } - else - { - return myCustomValue; - } - } - void DynamicsValue::setValue( const DynamicsEnum value ) - { - myEnum = value; - } - void DynamicsValue::setValue( const std::string& value ) - { - bool found = false; - DynamicsEnum temp = parseDynamicsEnum( value, found ); - if ( found ) - { - myEnum = temp; - } - else - { - setValue( DynamicsEnum::otherDynamics ); - myCustomValue = value; - } - } - DynamicsValue parseDynamicsValue( const std::string& value ) - { - return DynamicsValue( value ); - } - - - std::string toString( const DynamicsValue& value ) - { - return value.getValueString(); - } - - - std::ostream& toStream( std::ostream& os, const DynamicsValue& value ) - { - return os << toString( value ); - } - - - std::ostream& operator<<( std::ostream& os, const DynamicsValue& value ) - { - return toStream( os, value ); - } - - } // namespace core - -} // namespace mx diff --git a/docs/OldCode/Enums.old.h b/docs/OldCode/Enums.old.h deleted file mode 100755 index ed30a3fd0..000000000 --- a/docs/OldCode/Enums.old.h +++ /dev/null @@ -1,1324 +0,0 @@ -// MusicXML Class Library -// Copyright (c) by Matthew James Briggs -// Distributed under the MIT License - -#pragma once - -#include "mx/core/EnumsBuiltin.h" - -namespace mx -{ - namespace core - { - enum class AboveBelow - { - above = 0, - below = 1 - }; - AboveBelow parseAboveBelow( const std::string& value ); - std::string toString( const AboveBelow value ); - std::ostream& toStream( std::ostream& os, const AboveBelow value ); - std::ostream& operator<<( std::ostream& os, const AboveBelow value ); - - enum class CssFontSize - { - xxSmall = 0, - xSmall = 1, - small = 2, - medium = 3, - large = 4, - xLarge = 5, - xxLarge = 6 - }; - CssFontSize parseCssFontSize( const std::string& value ); - std::string toString( const CssFontSize value ); - std::ostream& toStream( std::ostream& os, const CssFontSize value ); - std::ostream& operator<<( std::ostream& os, const CssFontSize value ); - - enum class EnclosureShape - { - rectangle = 0, - square = 1, - oval = 2, - circle = 3, - bracket = 4, - triangle = 5, - diamond = 6, - none = 7 - }; - EnclosureShape parseEnclosureShape( const std::string& value ); - std::string toString( const EnclosureShape value ); - std::ostream& toStream( std::ostream& os, const EnclosureShape value ); - std::ostream& operator<<( std::ostream& os, const EnclosureShape value ); - - enum class FermataShape - { - normal = 0, - angled = 1, - square = 2, - emptystring = 3 - }; - FermataShape parseFermataShape( const std::string& value ); - std::string toString( const FermataShape value ); - std::ostream& toStream( std::ostream& os, const FermataShape value ); - std::ostream& operator<<( std::ostream& os, const FermataShape value ); - - enum class FontStyle - { - normal = 0, - italic = 1 - }; - FontStyle parseFontStyle( const std::string& value ); - std::string toString( const FontStyle value ); - std::ostream& toStream( std::ostream& os, const FontStyle value ); - std::ostream& operator<<( std::ostream& os, const FontStyle value ); - - enum class FontWeight - { - normal = 0, - bold = 1 - }; - FontWeight parseFontWeight( const std::string& value ); - std::string toString( const FontWeight value ); - std::ostream& toStream( std::ostream& os, const FontWeight value ); - std::ostream& operator<<( std::ostream& os, const FontWeight value ); - - enum class LeftCenterRight - { - left = 0, - center = 1, - right = 2 - }; - LeftCenterRight parseLeftCenterRight( const std::string& value ); - std::string toString( const LeftCenterRight value ); - std::ostream& toStream( std::ostream& os, const LeftCenterRight value ); - std::ostream& operator<<( std::ostream& os, const LeftCenterRight value ); - - enum class LeftRight - { - left = 0, - right = 1 - }; - LeftRight parseLeftRight( const std::string& value ); - std::string toString( const LeftRight value ); - std::ostream& toStream( std::ostream& os, const LeftRight value ); - std::ostream& operator<<( std::ostream& os, const LeftRight value ); - - enum class LineShape - { - straight = 0, - curved = 1 - }; - LineShape parseLineShape( const std::string& value ); - std::string toString( const LineShape value ); - std::ostream& toStream( std::ostream& os, const LineShape value ); - std::ostream& operator<<( std::ostream& os, const LineShape value ); - - enum class LineType - { - solid = 0, - dashed = 1, - dotted = 2, - wavy = 3 - }; - LineType parseLineType( const std::string& value ); - std::string toString( const LineType value ); - std::ostream& toStream( std::ostream& os, const LineType value ); - std::ostream& operator<<( std::ostream& os, const LineType value ); - - enum class MuteEnum - { - on = 0, - off = 1, - straight = 2, - cup = 3, - harmonNoStem = 4, - harmonStem = 5, - bucket = 6, - plunger = 7, - hat = 8, - solotone = 9, - practice = 10, - stopMute = 11, - stopHand = 12, - echo = 13, - palm = 14 - }; - MuteEnum parseMuteEnum( const std::string& value ); - std::string toString( const MuteEnum value ); - std::ostream& toStream( std::ostream& os, const MuteEnum value ); - std::ostream& operator<<( std::ostream& os, const MuteEnum value ); - - enum class OverUnder - { - over = 0, - under = 1 - }; - OverUnder parseOverUnder( const std::string& value ); - std::string toString( const OverUnder value ); - std::ostream& toStream( std::ostream& os, const OverUnder value ); - std::ostream& operator<<( std::ostream& os, const OverUnder value ); - - enum class SemiPitchedEnum - { - high = 0, - mediumHigh = 1, - medium = 2, - mediumLow = 3, - low = 4, - veryLow = 5 - }; - SemiPitchedEnum parseSemiPitchedEnum( const std::string& value ); - std::string toString( const SemiPitchedEnum value ); - std::ostream& toStream( std::ostream& os, const SemiPitchedEnum value ); - std::ostream& operator<<( std::ostream& os, const SemiPitchedEnum value ); - - enum class StartNote - { - upper = 0, - main = 1, - below = 2 - }; - StartNote parseStartNote( const std::string& value ); - std::string toString( const StartNote value ); - std::ostream& toStream( std::ostream& os, const StartNote value ); - std::ostream& operator<<( std::ostream& os, const StartNote value ); - - enum class StartStop - { - start = 0, - stop = 1 - }; - StartStop parseStartStop( const std::string& value ); - std::string toString( const StartStop value ); - std::ostream& toStream( std::ostream& os, const StartStop value ); - std::ostream& operator<<( std::ostream& os, const StartStop value ); - - enum class StartStopContinue - { - start = 0, - stop = 1, - continue_ = 2 - }; - StartStopContinue parseStartStopContinue( const std::string& value ); - std::string toString( const StartStopContinue value ); - std::ostream& toStream( std::ostream& os, const StartStopContinue value ); - std::ostream& operator<<( std::ostream& os, const StartStopContinue value ); - - enum class StartStopSingle - { - start = 0, - stop = 1, - single = 2 - }; - StartStopSingle parseStartStopSingle( const std::string& value ); - std::string toString( const StartStopSingle value ); - std::ostream& toStream( std::ostream& os, const StartStopSingle value ); - std::ostream& operator<<( std::ostream& os, const StartStopSingle value ); - - enum class SymbolSize - { - full = 0, - cue = 1, - large = 2 - }; - SymbolSize parseSymbolSize( const std::string& value ); - std::string toString( const SymbolSize value ); - std::ostream& toStream( std::ostream& os, const SymbolSize value ); - std::ostream& operator<<( std::ostream& os, const SymbolSize value ); - - enum class TextDirection - { - ltr = 0, - rtl = 1, - lro = 2, - rlo = 3 - }; - TextDirection parseTextDirection( const std::string& value ); - std::string toString( const TextDirection value ); - std::ostream& toStream( std::ostream& os, const TextDirection value ); - std::ostream& operator<<( std::ostream& os, const TextDirection value ); - - enum class TopBottom - { - top = 0, - bottom = 1 - }; - TopBottom parseTopBottom( const std::string& value ); - std::string toString( const TopBottom value ); - std::ostream& toStream( std::ostream& os, const TopBottom value ); - std::ostream& operator<<( std::ostream& os, const TopBottom value ); - - enum class TrillStep - { - whole = 0, - half = 1, - unison = 2 - }; - TrillStep parseTrillStep( const std::string& value ); - std::string toString( const TrillStep value ); - std::ostream& toStream( std::ostream& os, const TrillStep value ); - std::ostream& operator<<( std::ostream& os, const TrillStep value ); - - enum class TwoNoteTurn - { - whole = 0, - half = 1, - none = 2 - }; - TwoNoteTurn parseTwoNoteTurn( const std::string& value ); - std::string toString( const TwoNoteTurn value ); - std::ostream& toStream( std::ostream& os, const TwoNoteTurn value ); - std::ostream& operator<<( std::ostream& os, const TwoNoteTurn value ); - - enum class UpDown - { - up = 0, - down = 1 - }; - UpDown parseUpDown( const std::string& value ); - std::string toString( const UpDown value ); - std::ostream& toStream( std::ostream& os, const UpDown value ); - std::ostream& operator<<( std::ostream& os, const UpDown value ); - - enum class UprightInverted - { - upright = 0, - inverted = 1 - }; - UprightInverted parseUprightInverted( const std::string& value ); - std::string toString( const UprightInverted value ); - std::ostream& toStream( std::ostream& os, const UprightInverted value ); - std::ostream& operator<<( std::ostream& os, const UprightInverted value ); - - enum class Valign - { - top = 0, - middle = 1, - bottom = 2, - baseline = 3 - }; - Valign parseValign( const std::string& value ); - std::string toString( const Valign value ); - std::ostream& toStream( std::ostream& os, const Valign value ); - std::ostream& operator<<( std::ostream& os, const Valign value ); - - enum class ValignImage - { - top = 0, - middle = 1, - bottom = 2 - }; - ValignImage parseValignImage( const std::string& value ); - std::string toString( const ValignImage value ); - std::ostream& toStream( std::ostream& os, const ValignImage value ); - std::ostream& operator<<( std::ostream& os, const ValignImage value ); - - enum class YesNo - { - yes = 0, - no = 1 - }; - YesNo parseYesNo( const std::string& value ); - std::string toString( const YesNo value ); - std::ostream& toStream( std::ostream& os, const YesNo value ); - std::ostream& operator<<( std::ostream& os, const YesNo value ); - - enum class CancelLocation - { - left = 0, - right = 1, - beforeBarline = 2 - }; - CancelLocation parseCancelLocation( const std::string& value ); - std::string toString( const CancelLocation value ); - std::ostream& toStream( std::ostream& os, const CancelLocation value ); - std::ostream& operator<<( std::ostream& os, const CancelLocation value ); - - enum class ClefSign - { - g = 0, - f = 1, - c = 2, - percussion = 3, - tab = 4, - jianpu = 5, - none = 6 - }; - ClefSign parseClefSign( const std::string& value ); - std::string toString( const ClefSign value ); - std::ostream& toStream( std::ostream& os, const ClefSign value ); - std::ostream& operator<<( std::ostream& os, const ClefSign value ); - - enum class ShowFrets - { - numbers = 0, - letters = 1 - }; - ShowFrets parseShowFrets( const std::string& value ); - std::string toString( const ShowFrets value ); - std::ostream& toStream( std::ostream& os, const ShowFrets value ); - std::ostream& operator<<( std::ostream& os, const ShowFrets value ); - - enum class StaffTypeEnum - { - ossia = 0, - cue = 1, - editorial = 2, - regular = 3, - alternate = 4 - }; - StaffTypeEnum parseStaffTypeEnum( const std::string& value ); - std::string toString( const StaffTypeEnum value ); - std::ostream& toStream( std::ostream& os, const StaffTypeEnum value ); - std::ostream& operator<<( std::ostream& os, const StaffTypeEnum value ); - - enum class TimeRelationEnum - { - parentheses = 0, - bracket = 1, - equals = 2, - slash = 3, - space = 4, - hyphen = 5 - }; - TimeRelationEnum parseTimeRelationEnum( const std::string& value ); - std::string toString( const TimeRelationEnum value ); - std::ostream& toStream( std::ostream& os, const TimeRelationEnum value ); - std::ostream& operator<<( std::ostream& os, const TimeRelationEnum value ); - - enum class TimeSeparator - { - none = 0, - horizontal = 1, - diagonal = 2, - vertical = 3, - adjacent = 4 - }; - TimeSeparator parseTimeSeparator( const std::string& value ); - std::string toString( const TimeSeparator value ); - std::ostream& toStream( std::ostream& os, const TimeSeparator value ); - std::ostream& operator<<( std::ostream& os, const TimeSeparator value ); - - enum class TimeSymbol - { - common = 0, - cut = 1, - singleNumber = 2, - note = 3, - dottedNote = 4, - normal = 5 - }; - TimeSymbol parseTimeSymbol( const std::string& value ); - std::string toString( const TimeSymbol value ); - std::ostream& toStream( std::ostream& os, const TimeSymbol value ); - std::ostream& operator<<( std::ostream& os, const TimeSymbol value ); - - enum class BackwardForward - { - backward = 0, - forward = 1 - }; - BackwardForward parseBackwardForward( const std::string& value ); - std::string toString( const BackwardForward value ); - std::ostream& toStream( std::ostream& os, const BackwardForward value ); - std::ostream& operator<<( std::ostream& os, const BackwardForward value ); - - enum class BarStyleEnum - { - regular = 0, - dotted = 1, - dashed = 2, - heavy = 3, - lightLight = 4, - lightHeavy = 5, - heavyLight = 6, - heavyHeavy = 7, - tick = 8, - short_ = 9, - none = 10 - }; - BarStyleEnum parseBarStyleEnum( const std::string& value ); - std::string toString( const BarStyleEnum value ); - std::ostream& toStream( std::ostream& os, const BarStyleEnum value ); - std::ostream& operator<<( std::ostream& os, const BarStyleEnum value ); - - enum class RightLeftMiddle - { - right = 0, - left = 1, - middle = 2 - }; - RightLeftMiddle parseRightLeftMiddle( const std::string& value ); - std::string toString( const RightLeftMiddle value ); - std::ostream& toStream( std::ostream& os, const RightLeftMiddle value ); - std::ostream& operator<<( std::ostream& os, const RightLeftMiddle value ); - - enum class StartStopDiscontinue - { - start = 0, - stop = 1, - discontinue = 2 - }; - StartStopDiscontinue parseStartStopDiscontinue( const std::string& value ); - std::string toString( const StartStopDiscontinue value ); - std::ostream& toStream( std::ostream& os, const StartStopDiscontinue value ); - std::ostream& operator<<( std::ostream& os, const StartStopDiscontinue value ); - - enum class Winged - { - none = 0, - straight = 1, - curved = 2, - doubleStraight = 3, - doubleCurved = 4 - }; - Winged parseWinged( const std::string& value ); - std::string toString( const Winged value ); - std::ostream& toStream( std::ostream& os, const Winged value ); - std::ostream& operator<<( std::ostream& os, const Winged value ); - - enum class BeaterValue - { - bow = 0, - chimeHammer = 1, - coin = 2, - finger = 3, - fingernail = 4, - fist = 5, - guiroScraper = 6, - hammer = 7, - hand = 8, - jazzStick = 9, - knittingNeedle = 10, - metalHammer = 11, - snareStick = 12, - spoonMallet = 13, - triangleBeater = 14, - triangleBeaterPlain = 15, - wireBrush = 16 - }; - BeaterValue parseBeaterValue( const std::string& value ); - std::string toString( const BeaterValue value ); - std::ostream& toStream( std::ostream& os, const BeaterValue value ); - std::ostream& operator<<( std::ostream& os, const BeaterValue value ); - - enum class DegreeSymbolValue - { - major = 0, - minor = 1, - augmented = 2, - diminished = 3, - halfDiminished = 4 - }; - DegreeSymbolValue parseDegreeSymbolValue( const std::string& value ); - std::string toString( const DegreeSymbolValue value ); - std::ostream& toStream( std::ostream& os, const DegreeSymbolValue value ); - std::ostream& operator<<( std::ostream& os, const DegreeSymbolValue value ); - - enum class DegreeTypeValue - { - add = 0, - alter = 1, - subtract = 2 - }; - DegreeTypeValue parseDegreeTypeValue( const std::string& value ); - std::string toString( const DegreeTypeValue value ); - std::ostream& toStream( std::ostream& os, const DegreeTypeValue value ); - std::ostream& operator<<( std::ostream& os, const DegreeTypeValue value ); - - enum class EffectEnum - { - anvil = 0, - autoHorn = 1, - birdWhistle = 2, - cannon = 3, - duckCall = 4, - gunShot = 5, - klaxonHorn = 6, - lionsRoar = 7, - policeWhistle = 8, - siren = 9, - slideWhistle = 10, - thunderSheet = 11, - windMachine = 12, - windWhistle = 13 - }; - EffectEnum parseEffectEnum( const std::string& value ); - std::string toString( const EffectEnum value ); - std::ostream& toStream( std::ostream& os, const EffectEnum value ); - std::ostream& operator<<( std::ostream& os, const EffectEnum value ); - - enum class GlassEnum - { - windChimes = 0 - }; - GlassEnum parseGlassEnum( const std::string& value ); - std::string toString( const GlassEnum value ); - std::ostream& toStream( std::ostream& os, const GlassEnum value ); - std::ostream& operator<<( std::ostream& os, const GlassEnum value ); - - enum class HarmonyType - { - explicit_ = 0, - implied = 1, - alternate = 2 - }; - HarmonyType parseHarmonyType( const std::string& value ); - std::string toString( const HarmonyType value ); - std::ostream& toStream( std::ostream& os, const HarmonyType value ); - std::ostream& operator<<( std::ostream& os, const HarmonyType value ); - - enum class KindValue - { - major = 0, - minor = 1, - augmented = 2, - diminished = 3, - dominant = 4, - majorSeventh = 5, - minorSeventh = 6, - diminishedSeventh = 7, - augmentedSeventh = 8, - halfDiminished = 9, - majorMinor = 10, - majorSixth = 11, - minorSixth = 12, - dominantNinth = 13, - majorNinth = 14, - minorNinth = 15, - dominant11Th = 16, - major11Th = 17, - minor11Th = 18, - dominant13Th = 19, - major13Th = 20, - minor13Th = 21, - suspendedSecond = 22, - suspendedFourth = 23, - neapolitan = 24, - italian = 25, - french = 26, - german = 27, - pedal = 28, - power = 29, - tristan = 30, - other = 31, - none = 32 - }; - KindValue parseKindValue( const std::string& value ); - std::string toString( const KindValue value ); - std::ostream& toStream( std::ostream& os, const KindValue value ); - std::ostream& operator<<( std::ostream& os, const KindValue value ); - - enum class LineEnd - { - up = 0, - down = 1, - both = 2, - arrow = 3, - none = 4 - }; - LineEnd parseLineEnd( const std::string& value ); - std::string toString( const LineEnd value ); - std::ostream& toStream( std::ostream& os, const LineEnd value ); - std::ostream& operator<<( std::ostream& os, const LineEnd value ); - - enum class MeasureNumberingValue - { - none = 0, - measure = 1, - system = 2 - }; - MeasureNumberingValue parseMeasureNumberingValue( const std::string& value ); - std::string toString( const MeasureNumberingValue value ); - std::ostream& toStream( std::ostream& os, const MeasureNumberingValue value ); - std::ostream& operator<<( std::ostream& os, const MeasureNumberingValue value ); - - enum class MembraneEnum - { - bassDrum = 0, - bassDrumOnSide = 1, - bongos = 2, - congaDrum = 3, - gobletDrum = 4, - militaryDrum = 5, - snareDrum = 6, - snareDrumSnaresOff = 7, - tambourine = 8, - tenorDrum = 9, - timbales = 10, - tomtom = 11 - }; - MembraneEnum parseMembraneEnum( const std::string& value ); - std::string toString( const MembraneEnum value ); - std::ostream& toStream( std::ostream& os, const MembraneEnum value ); - std::ostream& operator<<( std::ostream& os, const MembraneEnum value ); - - enum class MetalEnum - { - almglocken = 0, - bell = 1, - bellPlate = 2, - brakeDrum = 3, - chineseCymbal = 4, - cowbell = 5, - crashCymbals = 6, - crotale = 7, - cymbalTongs = 8, - domedGong = 9, - fingerCymbals = 10, - flexatone = 11, - gong = 12, - hiHat = 13, - highHatCymbals = 14, - handbell = 15, - sistrum = 16, - sizzleCymbal = 17, - sleighBells = 18, - suspendedCymbal = 19, - tamTam = 20, - triangle = 21, - vietnameseHat = 22 - }; - MetalEnum parseMetalEnum( const std::string& value ); - std::string toString( const MetalEnum value ); - std::ostream& toStream( std::ostream& os, const MetalEnum value ); - std::ostream& operator<<( std::ostream& os, const MetalEnum value ); - - enum class OnOff - { - on = 0, - off = 1 - }; - OnOff parseOnOff( const std::string& value ); - std::string toString( const OnOff value ); - std::ostream& toStream( std::ostream& os, const OnOff value ); - std::ostream& operator<<( std::ostream& os, const OnOff value ); - - enum class PitchedEnum - { - chimes = 0, - glockenspiel = 1, - mallet = 2, - marimba = 3, - tubularChimes = 4, - vibraphone = 5, - xylophone = 6 - }; - PitchedEnum parsePitchedEnum( const std::string& value ); - std::string toString( const PitchedEnum value ); - std::ostream& toStream( std::ostream& os, const PitchedEnum value ); - std::ostream& operator<<( std::ostream& os, const PitchedEnum value ); - - enum class PrincipalVoiceSymbol - { - hauptstimme = 0, - nebenstimme = 1, - plain = 2, - none = 3 - }; - PrincipalVoiceSymbol parsePrincipalVoiceSymbol( const std::string& value ); - std::string toString( const PrincipalVoiceSymbol value ); - std::ostream& toStream( std::ostream& os, const PrincipalVoiceSymbol value ); - std::ostream& operator<<( std::ostream& os, const PrincipalVoiceSymbol value ); - - enum class StartStopChangeContinue - { - start = 0, - stop = 1, - change = 2, - continue_ = 3 - }; - StartStopChangeContinue parseStartStopChangeContinue( const std::string& value ); - std::string toString( const StartStopChangeContinue value ); - std::ostream& toStream( std::ostream& os, const StartStopChangeContinue value ); - std::ostream& operator<<( std::ostream& os, const StartStopChangeContinue value ); - - enum class TipDirection - { - up = 0, - down = 1, - left = 2, - right = 3, - northwest = 4, - northeast = 5, - southeast = 6, - southwest = 7 - }; - TipDirection parseTipDirection( const std::string& value ); - std::string toString( const TipDirection value ); - std::ostream& toStream( std::ostream& os, const TipDirection value ); - std::ostream& operator<<( std::ostream& os, const TipDirection value ); - - enum class StickLocationEnum - { - center = 0, - rim = 1, - cymbalBell = 2, - cymbalEdge = 3 - }; - StickLocationEnum parseStickLocationEnum( const std::string& value ); - std::string toString( const StickLocationEnum value ); - std::ostream& toStream( std::ostream& os, const StickLocationEnum value ); - std::ostream& operator<<( std::ostream& os, const StickLocationEnum value ); - - enum class StickMaterialEnum - { - soft = 0, - medium = 1, - hard = 2, - shaded = 3, - x = 4 - }; - StickMaterialEnum parseStickMaterialEnum( const std::string& value ); - std::string toString( const StickMaterialEnum value ); - std::ostream& toStream( std::ostream& os, const StickMaterialEnum value ); - std::ostream& operator<<( std::ostream& os, const StickMaterialEnum value ); - - enum class StickTypeEnum - { - bassDrum = 0, - doubleBassDrum = 1, - timpani = 2, - xylophone = 3, - yarn = 4 - }; - StickTypeEnum parseStickTypeEnum( const std::string& value ); - std::string toString( const StickTypeEnum value ); - std::ostream& toStream( std::ostream& os, const StickTypeEnum value ); - std::ostream& operator<<( std::ostream& os, const StickTypeEnum value ); - - enum class UpDownStopContinue - { - up = 0, - down = 1, - stop = 2, - continue_ = 3 - }; - UpDownStopContinue parseUpDownStopContinue( const std::string& value ); - std::string toString( const UpDownStopContinue value ); - std::ostream& toStream( std::ostream& os, const UpDownStopContinue value ); - std::ostream& operator<<( std::ostream& os, const UpDownStopContinue value ); - - enum class WedgeType - { - crescendo = 0, - diminuendo = 1, - stop = 2, - continue_ = 3 - }; - WedgeType parseWedgeType( const std::string& value ); - std::string toString( const WedgeType value ); - std::ostream& toStream( std::ostream& os, const WedgeType value ); - std::ostream& operator<<( std::ostream& os, const WedgeType value ); - - enum class WoodEnum - { - boardClapper = 0, - cabasa = 1, - castanets = 2, - claves = 3, - guiro = 4, - logDrum = 5, - maraca = 6, - maracas = 7, - ratchet = 8, - sandpaperBlocks = 9, - slitDrum = 10, - templeBlock = 11, - vibraslap = 12, - woodBlock = 13 - }; - WoodEnum parseWoodEnum( const std::string& value ); - std::string toString( const WoodEnum value ); - std::ostream& toStream( std::ostream& os, const WoodEnum value ); - std::ostream& operator<<( std::ostream& os, const WoodEnum value ); - - enum class MarginType - { - odd = 0, - even = 1, - both = 2 - }; - MarginType parseMarginType( const std::string& value ); - std::string toString( const MarginType value ); - std::ostream& toStream( std::ostream& os, const MarginType value ); - std::ostream& operator<<( std::ostream& os, const MarginType value ); - - enum class NoteSizeType - { - cue = 0, - grace = 1, - large = 2 - }; - NoteSizeType parseNoteSizeType( const std::string& value ); - std::string toString( const NoteSizeType value ); - std::ostream& toStream( std::ostream& os, const NoteSizeType value ); - std::ostream& operator<<( std::ostream& os, const NoteSizeType value ); - - enum class AccidentalValue - { - sharp = 0, - natural = 1, - flat = 2, - doubleSharp = 3, - sharpSharp = 4, - flatFlat = 5, - naturalSharp = 6, - naturalFlat = 7, - quarterFlat = 8, - quarterSharp = 9, - threeQuartersFlat = 10, - threeQuartersSharp = 11, - sharpDown = 12, - sharpUp = 13, - naturalDown = 14, - naturalUp = 15, - flatDown = 16, - flatUp = 17, - tripleSharp = 18, - tripleFlat = 19, - slashQuarterSharp = 20, - slashSharp = 21, - slashFlat = 22, - doubleSlashFlat = 23, - sharp1 = 24, - sharp2 = 25, - sharp3 = 26, - sharp5 = 27, - flat1 = 28, - flat2 = 29, - flat3 = 30, - flat4 = 31, - sori = 32, - koron = 33 - }; - AccidentalValue parseAccidentalValue( const std::string& value ); - std::string toString( const AccidentalValue value ); - std::ostream& toStream( std::ostream& os, const AccidentalValue value ); - std::ostream& operator<<( std::ostream& os, const AccidentalValue value ); - - enum class ArrowDirectionEnum - { - left = 0, - up = 1, - right = 2, - down = 3, - northwest = 4, - northeast = 5, - southeast = 6, - southwest = 7, - leftRight = 8, - upDown = 9, - northwestSoutheast = 10, - northeastSouthwest = 11, - other = 12 - }; - ArrowDirectionEnum parseArrowDirectionEnum( const std::string& value ); - std::string toString( const ArrowDirectionEnum value ); - std::ostream& toStream( std::ostream& os, const ArrowDirectionEnum value ); - std::ostream& operator<<( std::ostream& os, const ArrowDirectionEnum value ); - - enum class ArrowStyleEnum - { - single = 0, - double_ = 1, - filled = 2, - hollow = 3, - paired = 4, - combined = 5, - other = 6 - }; - ArrowStyleEnum parseArrowStyleEnum( const std::string& value ); - std::string toString( const ArrowStyleEnum value ); - std::ostream& toStream( std::ostream& os, const ArrowStyleEnum value ); - std::ostream& operator<<( std::ostream& os, const ArrowStyleEnum value ); - - enum class BeamValue - { - begin = 0, - continue_ = 1, - end = 2, - forwardHook = 3, - backwardHook = 4 - }; - BeamValue parseBeamValue( const std::string& value ); - std::string toString( const BeamValue value ); - std::ostream& toStream( std::ostream& os, const BeamValue value ); - std::ostream& operator<<( std::ostream& os, const BeamValue value ); - - enum class BreathMarkValue - { - emptystring = 0, - comma = 1, - tick = 2 - }; - BreathMarkValue parseBreathMarkValue( const std::string& value ); - std::string toString( const BreathMarkValue value ); - std::ostream& toStream( std::ostream& os, const BreathMarkValue value ); - std::ostream& operator<<( std::ostream& os, const BreathMarkValue value ); - - enum class CircularArrowEnum - { - clockwise = 0, - anticlockwise = 1 - }; - CircularArrowEnum parseCircularArrowEnum( const std::string& value ); - std::string toString( const CircularArrowEnum value ); - std::ostream& toStream( std::ostream& os, const CircularArrowEnum value ); - std::ostream& operator<<( std::ostream& os, const CircularArrowEnum value ); - - enum class Fan - { - accel = 0, - rit = 1, - none = 2 - }; - Fan parseFan( const std::string& value ); - std::string toString( const Fan value ); - std::ostream& toStream( std::ostream& os, const Fan value ); - std::ostream& operator<<( std::ostream& os, const Fan value ); - - enum class HandbellValue - { - damp = 0, - echo = 1, - gyro = 2, - handMartellato = 3, - malletLift = 4, - malletTable = 5, - martellato = 6, - martellatoLift = 7, - mutedMartellato = 8, - pluckLift = 9, - swing = 10 - }; - HandbellValue parseHandbellValue( const std::string& value ); - std::string toString( const HandbellValue value ); - std::ostream& toStream( std::ostream& os, const HandbellValue value ); - std::ostream& operator<<( std::ostream& os, const HandbellValue value ); - - enum class HoleClosedLocation - { - right = 0, - bottom = 1, - left = 2, - top = 3 - }; - HoleClosedLocation parseHoleClosedLocation( const std::string& value ); - std::string toString( const HoleClosedLocation value ); - std::ostream& toStream( std::ostream& os, const HoleClosedLocation value ); - std::ostream& operator<<( std::ostream& os, const HoleClosedLocation value ); - - enum class HoleClosedValue - { - yes = 0, - no = 1, - half = 2 - }; - HoleClosedValue parseHoleClosedValue( const std::string& value ); - std::string toString( const HoleClosedValue value ); - std::ostream& toStream( std::ostream& os, const HoleClosedValue value ); - std::ostream& operator<<( std::ostream& os, const HoleClosedValue value ); - - enum class NoteTypeValue - { - oneThousandTwentyFourth = 0, - fiveHundredTwelfth = 1, - twoHundredFifthySixth = 2, - oneHundredTwentyEighth = 3, - sixtyFourth = 4, - thirtySecond = 5, - sixteenth = 6, - eighth = 7, - quarter = 8, - half = 9, - whole = 10, - breve = 11, - long_ = 12, - maxima = 13 - }; - NoteTypeValue parseNoteTypeValue( const std::string& value ); - std::string toString( const NoteTypeValue value ); - std::ostream& toStream( std::ostream& os, const NoteTypeValue value ); - std::ostream& operator<<( std::ostream& os, const NoteTypeValue value ); - - enum class NoteheadValue - { - slash = 0, - triangle = 1, - diamond = 2, - square = 3, - cross = 4, - x = 5, - circleX = 6, - invertedTriangle = 7, - arrowDown = 8, - arrowUp = 9, - slashed = 10, - backSlashed = 11, - normal = 12, - cluster = 13, - circleDot = 14, - leftTriangle = 15, - rectangle = 16, - none = 17, - do_ = 18, - re = 19, - mi = 20, - fa = 21, - faUp = 22, - so = 23, - la = 24, - ti = 25 - }; - NoteheadValue parseNoteheadValue( const std::string& value ); - std::string toString( const NoteheadValue value ); - std::ostream& toStream( std::ostream& os, const NoteheadValue value ); - std::ostream& operator<<( std::ostream& os, const NoteheadValue value ); - - enum class ShowTuplet - { - actual = 0, - both = 1, - none = 2 - }; - ShowTuplet parseShowTuplet( const std::string& value ); - std::string toString( const ShowTuplet value ); - std::ostream& toStream( std::ostream& os, const ShowTuplet value ); - std::ostream& operator<<( std::ostream& os, const ShowTuplet value ); - - enum class StemValue - { - down = 0, - up = 1, - double_ = 2, - none = 3 - }; - StemValue parseStemValue( const std::string& value ); - std::string toString( const StemValue value ); - std::ostream& toStream( std::ostream& os, const StemValue value ); - std::ostream& operator<<( std::ostream& os, const StemValue value ); - - enum class StepEnum - { - a = 0, - b = 1, - c = 2, - d = 3, - e = 4, - f = 5, - g = 6 - }; - StepEnum parseStepEnum( const std::string& value ); - std::string toString( const StepEnum value ); - std::ostream& toStream( std::ostream& os, const StepEnum value ); - std::ostream& operator<<( std::ostream& os, const StepEnum value ); - - enum class SyllabicEnum - { - single = 0, - begin = 1, - end = 2, - middle = 3 - }; - SyllabicEnum parseSyllabicEnum( const std::string& value ); - std::string toString( const SyllabicEnum value ); - std::ostream& toStream( std::ostream& os, const SyllabicEnum value ); - std::ostream& operator<<( std::ostream& os, const SyllabicEnum value ); - - enum class GroupBarlineValue - { - yes = 0, - no = 1, - mensurstrich = 2 - }; - GroupBarlineValue parseGroupBarlineValue( const std::string& value ); - std::string toString( const GroupBarlineValue value ); - std::ostream& toStream( std::ostream& os, const GroupBarlineValue value ); - std::ostream& operator<<( std::ostream& os, const GroupBarlineValue value ); - - enum class GroupSymbolValue - { - none = 0, - brace = 1, - line = 2, - bracket = 3, - square = 4 - }; - GroupSymbolValue parseGroupSymbolValue( const std::string& value ); - std::string toString( const GroupSymbolValue value ); - std::ostream& toStream( std::ostream& os, const GroupSymbolValue value ); - std::ostream& operator<<( std::ostream& os, const GroupSymbolValue value ); - - enum class ModeEnum - { - major = 0, - minor = 1, - dorian = 2, - phrygian = 3, - lydian = 4, - mixolydian = 5, - aeolian = 6, - ionian = 7, - locrian = 8, - none = 9, - other = 10 - }; - ModeEnum parseModeEnum( const std::string& value ); - ModeEnum parseModeEnum( const std::string& value, bool& success ); - std::string toString( const ModeEnum value ); - std::ostream& toStream( std::ostream& os, const ModeEnum value ); - std::ostream& operator<<( std::ostream& os, const ModeEnum value ); - - class ModeValue - { - public: - explicit ModeValue( const ModeEnum value ); - explicit ModeValue( const std::string& value ); - ModeValue(); - ModeEnum getValue() const; - std::string getValueString() const; - void setValue( const ModeEnum value ); - void setValue( const std::string& value ); - private: - ModeEnum myEnum; - std::string myCustomValue; - }; - ModeValue parseModeValue( const std::string& value ); - std::string toString( const ModeValue& value ); - std::ostream& toStream( std::ostream& os, const ModeValue& value ); - std::ostream& operator<<( std::ostream& os, const ModeValue& value ); - - enum class DistanceTypeEnum - { - beam = 0, - hyphen = 1, - other = 2 - }; - DistanceTypeEnum parseDistanceTypeEnum( const std::string& value ); - DistanceTypeEnum parseDistanceTypeEnum( const std::string& value, bool& success ); - std::string toString( const DistanceTypeEnum value ); - std::ostream& toStream( std::ostream& os, const DistanceTypeEnum value ); - std::ostream& operator<<( std::ostream& os, const DistanceTypeEnum value ); - - class DistanceType - { - public: - explicit DistanceType( const DistanceTypeEnum value ); - explicit DistanceType( const std::string& value ); - DistanceType(); - DistanceTypeEnum getValue() const; - std::string getValueString() const; - void setValue( const DistanceTypeEnum value ); - void setValue( const std::string& value ); - private: - DistanceTypeEnum myEnum; - std::string myCustomValue; - }; - DistanceType parseDistanceType( const std::string& value ); - std::string toString( const DistanceType& value ); - std::ostream& toStream( std::ostream& os, const DistanceType& value ); - std::ostream& operator<<( std::ostream& os, const DistanceType& value ); - - enum class LineWidthTypeEnum - { - beam = 0, - bracket = 1, - dashes = 2, - enclosure = 3, - ending = 4, - extend = 5, - heavyBarline = 6, - leger = 7, - lightBarline = 8, - octaveShift = 9, - pedal = 10, - slurMiddle = 11, - slurTip = 12, - staff = 13, - stem = 14, - tieMiddle = 15, - tieTip = 16, - tupletBracket = 17, - wedge = 18, - other = 19 - }; - LineWidthTypeEnum parseLineWidthTypeEnum( const std::string& value ); - LineWidthTypeEnum parseLineWidthTypeEnum( const std::string& value, bool& success ); - std::string toString( const LineWidthTypeEnum value ); - std::ostream& toStream( std::ostream& os, const LineWidthTypeEnum value ); - std::ostream& operator<<( std::ostream& os, const LineWidthTypeEnum value ); - - class LineWidthType - { - public: - explicit LineWidthType( const LineWidthTypeEnum value ); - explicit LineWidthType( const std::string& value ); - LineWidthType(); - LineWidthTypeEnum getValue() const; - std::string getValueString() const; - void setValue( const LineWidthTypeEnum value ); - void setValue( const std::string& value ); - private: - LineWidthTypeEnum myEnum; - std::string myCustomValue; - }; - LineWidthType parseLineWidthType( const std::string& value ); - std::string toString( const LineWidthType& value ); - std::ostream& toStream( std::ostream& os, const LineWidthType& value ); - std::ostream& operator<<( std::ostream& os, const LineWidthType& value ); - - enum class DynamicsEnum - { - p = 0, - pp = 1, - ppp = 2, - pppp = 3, - ppppp = 4, - pppppp = 5, - f = 6, - ff = 7, - fff = 8, - ffff = 9, - fffff = 10, - ffffff = 11, - mp = 12, - mf = 13, - sf = 14, - sfp = 15, - sfpp = 16, - fp = 17, - rf = 18, - rfz = 19, - sfz = 20, - sffz = 21, - fz = 22, - otherDynamics = 23 - }; - DynamicsEnum parseDynamicsEnum( const std::string& value ); - DynamicsEnum parseDynamicsEnum( const std::string& value, bool& success ); - std::string toString( const DynamicsEnum value ); - std::ostream& toStream( std::ostream& os, const DynamicsEnum value ); - std::ostream& operator<<( std::ostream& os, const DynamicsEnum value ); - - class DynamicsValue - { - public: - explicit DynamicsValue( const DynamicsEnum value ); - explicit DynamicsValue( const std::string& value ); - DynamicsValue(); - DynamicsEnum getValue() const; - std::string getValueString() const; - void setValue( const DynamicsEnum value ); - void setValue( const std::string& value ); - private: - DynamicsEnum myEnum; - std::string myCustomValue; - }; - DynamicsValue parseDynamicsValue( const std::string& value ); - std::string toString( const DynamicsValue& value ); - std::ostream& toStream( std::ostream& os, const DynamicsValue& value ); - std::ostream& operator<<( std::ostream& os, const DynamicsValue& value ); - } -} diff --git a/gen/version-a/ElementsOrder.xlsx b/gen/version-a/ElementsOrder.xlsx deleted file mode 100755 index ab9add4eecd9bc2fb146f4f0ab1f6d0d5f200c5d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 85020 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 q5Ihw%I88dL_hUN6>?8wa2zJNvb?H?o! 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%0DZRe{=Yw2evD8B>g+Yhw`*wcW%S-jw=E#D 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" << "\n" -code << "\n" -first_if = true -members.each do |m| - - code << tab << tab << tab << tab - if !first_if - code << "else " - end - first_if = false - code << "if( elementName == \"#{m.element_name}\" )" << "\n" - code << tab << tab << tab << tab << "{" << "\n" - if m.is_set -code << " auto #{m.element_name_for_cpp.uncapitalize} = make#{m.element_name_for_cpp.uncapitalize}();" << "\n" -code << " isSuccess &= #{m.element_name_for_cpp.uncapitalize}->fromXElement( message, *it );" << "\n" -code << "\n" -code << " if( !#{m.is_first_added_variable} && #{m.my_variable_name}.size() == 1 )" << "\n" -code << " {" << "\n" -code << " *( #{m.my_variable_name}.begin() ) = #{m.element_name_for_cpp.uncapitalize};" << "\n" -code << " #{m.is_first_added_variable} = true;" << "\n" -code << " }" << "\n" -code << " else" << "\n" -code << " {" << "\n" -code << " #{m.my_variable_name}.push_back( #{m.element_name_for_cpp.uncapitalize} );" << "\n" -code << " #{m.is_first_added_variable} = true;" << "\n" -code << " }" << "\n" - elsif m.is_required -code << " #{m.is_found_variable} = true;" << "\n" -code << " isSuccess &= #{m.my_variable_name}->fromXElement( message, *it );" << "\n" - else -code << " myHas#{m.element_name_for_cpp} = true;" << "\n" -code << " isSuccess &= #{m.my_variable_name}->fromXElement( message, *it );" << "\n" - end - code << tab << tab << tab << tab << "}" << "\n" -end -code << tab << tab << tab << tab << "else" << "\n" -code << tab << tab << tab << tab << "{" << "\n" - -members.each do |m| - if m.is_required -code << " if( !#{m.is_found_variable} )" << "\n" -code << " {" << "\n" -code << " isSuccess = false;" << "\n" -code << " message << \"#{group_class_name}: '#{m.element_name}' element is required but was not found\" << std::endl;" << "\n" -code << " }" << "\n" - end -end -code << " break;" << "\n" -code << tab << tab << tab << tab << "}" << "\n" -code << tab << tab << tab << "}" << "\n" -code << tab << tab << tab << "return isSuccess;" << "\n" -code << tab << tab << "}" << "\n" - -puts code.string \ No newline at end of file diff --git a/gen/version-a/attributes.rb b/gen/version-a/attributes.rb deleted file mode 100755 index 089e37e19..000000000 --- a/gen/version-a/attributes.rb +++ /dev/null @@ -1,310 +0,0 @@ -require 'stringio' - -require_relative 'listEnums.rb' -require_relative 'listClassesInEnumsH' -require_relative 'listSpecialClasses' -require_relative 'listDecimals' -require_relative 'listIntegers' -require_relative 'listStrings' - -class IntermediateStruct - attr_accessor :const - attr_accessor :typename - attr_accessor :prefix - attr_accessor :name - def to_s - "const: #{const}, typename: #{typename}, prefix: #{prefix}, name: #{name}, xmlname: #{xmlname}" - end - - def xmlname - temp = name.split(/([[:upper:]][[:lower:]]*)/).delete_if(&:empty?).join("-").downcase - temp.gsub('_',' ') - end - def initialize - @const = false - @typename = "" - @prefix = "" - @name = "" - end -end - - -class MemberInfo - attr_accessor :type - attr_accessor :name - attr_accessor :is_required - attr_accessor :xmlname - def to_s - "type: #{type}, name: #{name}, is_required: #{is_required}, xmlname: #{xmlname}" - end - def initialize - @type = "" - @name = "" - @is_required = false - @xmlname = "" - end - - def name_capitalized - ( name.slice(0,1).capitalize + name.slice(1..-1) ).gsub('_',' ') - end - - def finders_bool - if is_required - "is#{name_capitalized}Found" - else - "has#{name_capitalized}" - end - - end - - def parsing_statement enums_list #, decimals_list, integers_list, strings_list, classes_in_enumh, specials_list - - if enums_list.include? type - "if( parseAttribute( message, it, className, isSuccess, #{name}, #{finders_bool}, \"#{xmlname}\", &parse#{type} ) ) { continue; }" - - else - "if( parseAttribute( message, it, className, isSuccess, #{name}, #{finders_bool}, \"#{xmlname}\" ) ) { continue; }" - - end - - end - -end - - -def from_xelement_code indent, enums_list, member_list, class_name - io = StringIO.new - io << indent << "bool #{class_name}::fromXElement( std::ostream& message, xml::XElement& xelement )" << "\n" - io << indent << "{" << "\n" - io << indent << " const char* const className = \"#{class_name}\";" << "\n" - io << indent << " bool isSuccess = true;" << "\n" - each_required_bool_init io, indent, enums_list, member_list - io << indent << "" << "\n" - io << indent << " auto it = xelement.attributesBegin();" << "\n" - io << indent << " auto endIter = xelement.attributesEnd();" << "\n" - io << indent << "" << "\n" - io << indent << " for( ; it != endIter; ++it )" << "\n" - io << indent << " {" << "\n" - each_iter_loop_code io, indent, enums_list, member_list - io << indent << " }" << "\n" - io << indent << "" << "\n" - each_required_bool_check io, indent, enums_list, member_list - io << indent << "" << "\n" - io << indent << " return isSuccess;" << "\n" - io << indent << "}" << "\n" - io.string -end - -def each_iter_loop_code io, indent, enums_list, member_list - member_list.each do |m| - io << indent << " #{m.parsing_statement(enums_list)}" << "\n" - end -end - -def each_required_bool_init io, indent, enums_list, member_list - member_list.each do |m| - if m.is_required - io << indent << " bool #{m.finders_bool} = false;" << "\n" - end - end -end - -def each_required_bool_check io, indent, enums_list, member_list - member_list.each do |m| - if m.is_required - io << indent << " if( !#{m.finders_bool} )" << "\n" - io << indent << " {" << "\n" - io << indent << " isSuccess = false;" << "\n" - io << indent << " message << className << \": 'number' is a required attribute but was not found\" << std::endl;" << "\n" - io << indent << " }" << "\n" - end - end -end - - -def implementAttributeImport class_name - - list_enums = listEnums - #list_classes_in_enums_h = listClassesInEnumsH - #list_special_classes = listSpecialClasses - #list_decimals = listDecimals - #list_integers = listIntegers - #list_strings = listStrings - - hlines = [] - hlines_last_member = -1 - clines = [] - - cline_first_include = -1 - cline_last_function_close = -1 - - File.open("../../src/mx/core/elements/#{class_name}.cpp", "r") do |f| - is_first_include_found = false - rx_first_include = /\#include/ - rx_function_close = / \}/ - - f.each_with_index do |line, index| - clines << line - - if !is_first_include_found - if ( line =~ rx_first_include ) != nil - cline_first_include = index - is_first_include_found = true - end - end - - if ( line =~ rx_function_close ) != nil - cline_last_function_close = index - end - end - end - - - - hintermediates = [] - - File.open("../../src/mx/core/elements/#{class_name}.h", "r") do |f| - #puts caller.first - rx_public = / public\:/ - is_member_list = false - f.each_with_index do |line, index| - hlines << line - - if ( line =~ rx_public ) != nil - is_member_list = true - #puts caller.first - next - elsif is_member_list - #puts caller.first - if ( line =~ /\s+[a-zA-Z0-9\_]+\s+[a-zA-Z0-9\_]+/ ) == nil - if ( line =~ /#{class_name}/ ) == nil - #puts line - #puts caller.first - is_member_list = false - hlines_last_member = index - end - else - #make the list of members here - rx_const_has = /\s+const\s+bool\s+(has)([a-zA-Z0-9\_]+)/ - rx_has = /\s+bool\s+(has)([a-zA-Z0-9\_]+)/ - rx_other = /\s+([a-zA-Z0-9\_]+)\s+([a-zA-Z0-9\_]+)/ - - #capture const has - if ( line =~ rx_const_has ) != nil - matches = line.match(rx_const_has) - if !matches.nil? - has_capture, name_capture = matches.captures - x = IntermediateStruct.new - x.const = true - x.typename = "bool" - x.prefix = has_capture - x.name = name_capture - hintermediates << x - end - - #capture regular has - elsif ( line =~ rx_has ) != nil - matches = line.match(rx_has) - if !matches.nil? - has_capture, name_capture = matches.captures - x = IntermediateStruct.new - x.const = false - x.typename = "bool" - x.prefix = has_capture - x.name = name_capture - hintermediates << x - end - - #capture non bools - elsif ( line =~ rx_other ) != nil - matches = line.match(rx_other) - if !matches.nil? - type_capture, name_capture = matches.captures - x = IntermediateStruct.new - x.const = false - x.typename = type_capture - x.prefix = "" - x.name = name_capture - hintermediates << x - end - end - end - end - end - end - - - - hmembers = [] - - hintermediates.each do |i| - - if !i.const && (i.typename.eql? "bool") && (i.prefix.eql? "has") && (i.name.eql? "Values") - next - end - - if !i.const && (i.typename.eql? "virtual") && (i.prefix.eql? "") && (i.name.eql? "std") - next - end - - info = MemberInfo.new - need_to_add = true - hmembers.each do |hmem| - if hmem.name.casecmp(i.name) == 0 - info = hmem - need_to_add = false - end - end - - if i.prefix.eql? "has" - info.is_required = i.const - else - info.name = i.name - info.type = i.typename - info.xmlname = i.xmlname - end - - - if need_to_add - need_to_add = false - hmembers << info - end - - end - -hmembers.delete_if { |x| ( x.name == nil ) || ( x.name.eql? "" ) } - - - - File.open("../../src/mx/core/elements/#{class_name}.h", "w") do |f| - hlines.each_with_index do |line, index| - if( index == hlines_last_member ) - f << "\n" - f << " bool fromXElement( std::ostream& message, xml::XElement& xelement );" << "\n" - end - f << line - end - end - - - File.open("../../src/mx/core/elements/#{class_name}.cpp", "w") do |f| - clines.each_with_index do |line, index| - if( index == cline_first_include ) - f << line - f << "\#include \"mx/core/FromXElement.h\"" << "\n" - next - end - - if( index == cline_last_function_close ) - f << line - f << "\n\n" - f << from_xelement_code( " ", list_enums, hmembers, class_name ) - next - end # end if( index == cline_last_function_close ) - f << line - end # end clines.each_with_index do |line, index| - end # end cfile write - -end # end of function - -implementAttributeImport "InvertedMordentAttributes" \ No newline at end of file diff --git a/gen/version-a/attributesLoop.rb b/gen/version-a/attributesLoop.rb deleted file mode 100755 index bf4766c13..000000000 --- a/gen/version-a/attributesLoop.rb +++ /dev/null @@ -1,22 +0,0 @@ -require_relative 'attributes.rb' -require 'pathname' -paths = Dir["../../src/mx/core/elements/*.h"] - -names = [] - -paths.each do |path| - names << File.basename( path, ".*" ) -end - -attributes_classes = [] - -names.each do |name| - rx = /[a-zA-Z0-9\_]+Attributes/ - if ( name =~ rx ) != nil - attributes_classes << name - end -end - -attributes_classes.each do |ac| - implementAttributeImport ac -end \ No newline at end of file diff --git a/gen/version-a/beatUnitGroup.rb b/gen/version-a/beatUnitGroup.rb deleted file mode 100755 index 5ba170825..000000000 --- a/gen/version-a/beatUnitGroup.rb +++ /dev/null @@ -1,130 +0,0 @@ - -require 'stringio' - -class String - def uncapitalize - self[0, 1].downcase + self[1..-1] - end -end - -class Member - attr_accessor :my_variable_name - attr_accessor :element_name - attr_accessor :is_set - attr_accessor :is_required - attr_accessor :element_name_for_cpp - - def initialize in_my_variable_name, in_element_name, in_description, in_element_name_for_cpp - @my_variable_name = in_my_variable_name - @element_name = in_element_name - @element_name_for_cpp = in_element_name_for_cpp - - if in_description.eql? "collection" - @is_set = true - @is_required = false - elsif in_description.eql? "required" - @is_set = false - @is_required = true - elsif in_description.eql? "optional" - @is_set = false - @is_required = false - else - @is_set = false - @is_required = false - end - end - - def is_found_variable - "is#{element_name_for_cpp}Found" - end - - def is_first_added_variable - "isFirst#{element_name_for_cpp}Added" - end - -end - -=begin -example_required_single = Member.new "myCreditWords", "credit-words", "required", "CreditWords" -example_optional_single = Member.new "myOptionalThing", "optional-thing", "optional", "OptionalThing" -example_collection = Member.new "myCatSet", "cat", "collection", "Cat" -=end - -group_class_name = "BeatUnitGroup" - -members = [] - -#sample code -members << Member.new( "myBeatUnit", "beat-unit", "required", "BeatUnit" ) -members << Member.new( "myBeatUnitDotSet", "beat-unit-dot", "collection", "BeatUnitDot" ) - -code = StringIO.new -tab = " " -code << tab << tab << "bool #{group_class_name}::fromXElement( std::ostream& message, xml::XElement& xelement )" << "\n" -code << tab << tab << "{" << "\n" -code << tab << tab << tab << "bool isSuccess = true;" << "\n" - -members.each do |m| - if m.is_required && !m.is_set - code << tab << tab << tab << "bool #{m.is_found_variable} = false;" << "\n" - elsif m.is_set - code << tab << tab << tab << "bool #{m.is_first_added_variable} = false;" << "\n" - end -end -code << "\n" -code << tab << tab << tab << "for( auto it = xelement.elementsBegin(); it != xelement.elementsEnd(); ++it )" << "\n" -code << tab << tab << tab << "{" << "\n" -code << tab << tab << tab << tab << "const std::string elementName = it->getName();" << "\n" -code << "\n" -first_if = true -members.each do |m| - - code << tab << tab << tab << tab - if !first_if - code << "else " - end - first_if = false - code << "if( elementName == \"#{m.element_name}\" )" << "\n" - code << tab << tab << tab << tab << "{" << "\n" - if m.is_set -code << " auto #{m.element_name_for_cpp.uncapitalize} = make#{m.element_name_for_cpp}();" << "\n" -code << " isSuccess &= #{m.element_name_for_cpp.uncapitalize}->fromXElement( message, *it );" << "\n" -code << "\n" -code << " if( !#{m.is_first_added_variable} && #{m.my_variable_name}.size() == 1 )" << "\n" -code << " {" << "\n" -code << " *( #{m.my_variable_name}.begin() ) = #{m.element_name_for_cpp.uncapitalize};" << "\n" -code << " #{m.is_first_added_variable} = true;" << "\n" -code << " }" << "\n" -code << " else" << "\n" -code << " {" << "\n" -code << " #{m.my_variable_name}.push_back( #{m.element_name_for_cpp.uncapitalize} );" << "\n" -code << " #{m.is_first_added_variable} = true;" << "\n" -code << " }" << "\n" - elsif m.is_required -code << " #{m.is_found_variable} = true;" << "\n" -code << " isSuccess &= #{m.my_variable_name}->fromXElement( message, *it );" << "\n" - else -code << " myHas#{m.element_name_for_cpp} = true;" << "\n" -code << " isSuccess &= #{m.my_variable_name}->fromXElement( message, *it );" << "\n" - end - code << tab << tab << tab << tab << "}" << "\n" -end -code << tab << tab << tab << tab << "else" << "\n" -code << tab << tab << tab << tab << "{" << "\n" - -members.each do |m| - if m.is_required -code << " if( !#{m.is_found_variable} )" << "\n" -code << " {" << "\n" -code << " isSuccess = false;" << "\n" -code << " message << \"#{group_class_name}: '#{m.element_name}' element is required but was not found\" << std::endl;" << "\n" -code << " }" << "\n" - end -end -code << " break;" << "\n" -code << tab << tab << tab << tab << "}" << "\n" -code << tab << tab << tab << "}" << "\n" -code << tab << tab << tab << "return isSuccess;" << "\n" -code << tab << tab << "}" << "\n" - -puts code.string \ No newline at end of file diff --git a/gen/version-a/build-for-apple.sh b/gen/version-a/build-for-apple.sh deleted file mode 100755 index f64ba8929..000000000 --- a/gen/version-a/build-for-apple.sh +++ /dev/null @@ -1,212 +0,0 @@ -#!/usr/bin/env bash -set -eo pipefail - -for tool in lipo xcodebuild mktemp uuidgen; do - if ! command -v ${tool} > /dev/null; then - echo "* Can't find executable '${tool}'" >&2 - exit 2 - fi -done - -# default values for optional parameters - -DEFAULT_BUILD_DIR="$(mktemp -d)/$(uuidgen)" -DEFAULT_TEST="false" -DEFAULT_CONFIGURATION="Release" -DEFAULT_CLEANUP="true" - -#################################################################################################################### -# Parsing Command Line Input -#################################################################################################################### - -usage() { - cat >&2 <&2 - exit 2 - fi -} - -parse_args() { - while [ ${#} -gt 0 ] ; do - case "${1}" in - # required - --outdir ) shift; OUTDIR="${1}" ;; - - # optional - --build-dir ) shift; BUILD_DIR="${1}" ;; - --test ) shift; TEST="${1}" ;; - --configuration ) shift; CONFIGURATION="${1}" ;; - --cleanup ) shift; CLEANUP="${1}" ;; - - --help ) usage; exit 0 ;; - *) - echo "ERROR: Unknown argument: ${1}" >&2 - usage - exit 2 - ;; - esac - shift - done - - BUILD_DIR="${BUILD_DIR:-${DEFAULT_BUILD_DIR}}" - TEST="${TEST:-${DEFAULT_TEST}}" - CLEANUP="${CLEANUP:-${DEFAULT_CLEANUP}}" - CONFIGURATION="${CONFIGURATION:-${DEFAULT_CONFIGURATION}}" - - # fail if required arguments are missing - required_arg "--outdir" "${OUTDIR}" - - # check that all optional args are also set by now (with defaults or passed args) - required_arg "--build-dir" "${BUILD_DIR}" - required_arg "--test" "${TEST}" - required_arg "--configuration" "${CONFIGURATION}" - required_arg "--cleanup" "${CLEANUP}" -} - - -#################################################################################################################### -# Helper Functions -#################################################################################################################### - -delete_build_dir() { - if [ "${CLEANUP}" = "true" ]; then - echo "deleting build dir" - rm -rf "${BUILD_DIR}" - fi; -} - -#################################################################################################################### -# Set Variables -#################################################################################################################### - -set_variables() { - # directories - this_script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" - mx_dir="${this_script_dir}/../.." - xcworkspace="${mx_dir}/xcode/mx.xcworkspace" - - # artifact names - ios_name="MxiOS" - ios_lib_name="lib${ios_name}" - ios_framework_name="${ios_name}.framework" - macos_name="MxmacOS" - macos_lib_name="lib${macos_name}" - macos_framework_name="${macos_name}.framework" - - # build-dir output paths - macos_build_path="${BUILD_DIR}/Build/Products/${CONFIGURATION}/${macos_framework_name}" - ios_build_path="${BUILD_DIR}/Build/Products/${CONFIGURATION}-iphoneos/${ios_framework_name}" - ios_simulator_build_path="${BUILD_DIR}/Build/Products/${CONFIGURATION}-iphonesimulator/${ios_framework_name}" - ios_build_binary="${ios_build_path}/${ios_name}" - ios_simulator_build_binary="${ios_simulator_build_path}/${ios_name}" - ios_binary_temp_path="${BUILD_DIR}/temp-fat-ios-binary" -} - -#################################################################################################################### -# Do Builds -#################################################################################################################### - -do_tests() { - if [ "${TEST}" -ne "true" ]; then - return 0 - fi; - - echo "TODO: test is not implemented, skipping" -} - -build_for_ios() { - - xcodebuild \ - -workspace "${xcworkspace}" \ - -scheme "${ios_name}" \ - build \ - -derivedDataPath "${BUILD_DIR}" \ - -destination 'generic/platform=iOS' \ - -destination 'generic/platform=iOS simulator' \ - -configuration "${CONFIGURATION}" -} - -build_for_macos() { - xcodebuild \ - -workspace "${xcworkspace}" \ - -scheme "${macos_name}" \ - build \ - -derivedDataPath "${BUILD_DIR}" \ - -destination 'generic/platform=macOS' \ - -destination 'platform=OS X,arch=x86_64' \ - -configuration "${CONFIGURATION}" -} - -create_ios_fat_binary() { - echo "create_ios_fat_binary" - rm -f "/tmp/MxiOS-x86_64" - lipo "${ios_simulator_build_binary}" -extract x86_64 -output "/tmp/MxiOS-x86_64" - - lipo -create -output "${ios_binary_temp_path}" \ - "${ios_build_binary}" \ - "/tmp/MxiOS-x86_64" - - # in the ios framework, replace the 'skinny' binary with the 'fat' one - cp -f "${ios_binary_temp_path}" "${ios_build_binary}" -} - -move_outputs() { - echo "move_outputs" - rm -rf "${OUTDIR}/${ios_framework_name}" - rm -rf "${OUTDIR}/${macos_framework_name}" - mv -f "${ios_build_path}/" "${OUTDIR}/" - mv -f "${macos_build_path}/" "${OUTDIR}/" -} - -trap 'delete_build_dir' EXIT SIGINT SIGTERM - -main() { - parse_args "${@}" - set_variables - - mkdir -p "${BUILD_DIR}" - mkdir -p "${OUTDIR}" - - if [ "${TEST}" = "true" ]; then - do_tests - fi; - - build_for_ios - build_for_macos - create_ios_fat_binary - move_outputs - delete_build_dir - echo "Output:" - echo "${OUTDIR}/${ios_framework_name}" - echo "${OUTDIR}/${macos_framework_name}" -} - -main "${@}" \ No newline at end of file diff --git a/gen/version-a/choices.rb b/gen/version-a/choices.rb deleted file mode 100755 index 15842ab0b..000000000 --- a/gen/version-a/choices.rb +++ /dev/null @@ -1,84 +0,0 @@ -require "stringio" - -enum_value_string = -' - - multipleRest = 0, - measureRepeat = 1, - beatRepeat = 2, - slash = 3 - - -' - -enum_symbols = [] - -enum_value_string.lines.each do |line| - - - rx = /\s+([a-zA-Z0-9\_]+)\s+/ - if ( line =~ rx ) != nil - - matches = line.match(rx) - - if !matches.nil? - caps = matches.captures - enum_symbol = caps[0] - enum_symbols << enum_symbol - - end - - end - -end - -class Enum - attr_accessor :symbol - def to_s - "symbol: #{symbol}, element: #{element}, caps: #{caps}," - end - - def initialize in_symbol - @symbol = in_symbol - end - - def element - clean = remove_trailing_underscore - dashed = clean.split(/([[:upper:]][[:lower:]]*)/).delete_if(&:empty?).join("-") - dashed.downcase - end - - def caps - clean = remove_trailing_underscore - clean.slice(0,1).capitalize + clean.slice(1..-1) - end - - def remove_trailing_underscore - rx = /([a-zA-Z0-9]+)/ - - if ( symbol =~ rx ) != nil - - matches = symbol.match(rx) - - if !matches.nil? - caps = matches.captures - without_underscore = caps[0] - return without_underscore - - end - - end - - end -end - - -puts " bool DisplayTextOrAccidentalText::fromXElement( std::ostream& message, xml::XElement& xelement )" -puts " {" -enum_symbols.each do |es| -e = Enum.new es -puts " MX_CHOICE_IF( #{e.symbol}, \"#{e.element}\", #{e.caps} );" -end -puts " MX_BAD_ELEMENT_FAILURE( CLASSNAME );" -puts " }" - diff --git a/gen/version-a/creditWordsGroup.rb b/gen/version-a/creditWordsGroup.rb deleted file mode 100755 index 4e7b49cea..000000000 --- a/gen/version-a/creditWordsGroup.rb +++ /dev/null @@ -1,131 +0,0 @@ - -require 'stringio' - -class String - def uncapitalize - self[0, 1].downcase + self[1..-1] - end -end - -class Member - attr_accessor :my_variable_name - attr_accessor :element_name - attr_accessor :is_set - attr_accessor :is_required - attr_accessor :element_name_for_cpp - - def initialize in_my_variable_name, in_element_name, in_description, in_element_name_for_cpp - @my_variable_name = in_my_variable_name - @element_name = in_element_name - @element_name_for_cpp = in_element_name_for_cpp - - if in_description.eql? "collection" - @is_set = true - @is_required = false - elsif in_description.eql? "required" - @is_set = false - @is_required = true - elsif in_description.eql? "optional" - @is_set = false - @is_required = false - else - @is_set = false - @is_required = false - end - end - - def is_found_variable - "is#{element_name_for_cpp}Found" - end - - def is_first_added_variable - "isFirst#{element_name_for_cpp}Added" - end - -end - -=begin -example_required_single = Member.new "myCreditWords", "credit-words", "required", "CreditWords" -example_optional_single = Member.new "myOptionalThing", "optional-thing", "optional", "OptionalThing" -example_collection = Member.new "myCatSet", "cat", "collection", "Cat" -=end - -group_class_name = "CreditWordsGroup" - -members = [] - -#sample code -members << Member.new( "myLinkSet", "link", "collection", "Link" ) -members << Member.new( "myBookmarkSet", "bookmark", "collection", "Bookmark" ) -members << Member.new( "myCreditWords", "credit-words", "required", "CreditWords" ) - -code = StringIO.new -tab = " " -code << tab << tab << "bool #{group_class_name}::fromXElement( std::ostream& message, xml::XElement& xelement )" << "\n" -code << tab << tab << "{" << "\n" -code << tab << tab << tab << "bool isSuccess = true;" << "\n" - -members.each do |m| - if m.is_required && !m.is_set - code << tab << tab << tab << "bool #{m.is_found_variable} = false;" << "\n" - elsif m.is_set - code << tab << tab << tab << "bool #{m.is_first_added_variable} = false;" << "\n" - end -end -code << "\n" -code << tab << tab << tab << "for( auto it = xelement.elementsBegin(); it != xelement.elementsEnd(); ++it )" << "\n" -code << tab << tab << tab << "{" << "\n" -code << tab << tab << tab << tab << "const std::string elementName = it->getName();" << "\n" -code << "\n" -first_if = true -members.each do |m| - - code << tab << tab << tab << tab - if !first_if - code << "else " - end - first_if = false - code << "if( elementName == \"#{m.element_name}\" )" << "\n" - code << tab << tab << tab << tab << "{" << "\n" - if m.is_set -code << " auto #{m.element_name_for_cpp.uncapitalize} = make#{m.element_name_for_cpp}();" << "\n" -code << " isSuccess &= #{m.element_name_for_cpp.uncapitalize}->fromXElement( message, *it );" << "\n" -code << "\n" -code << " if( !#{m.is_first_added_variable} && #{m.my_variable_name}.size() == 1 )" << "\n" -code << " {" << "\n" -code << " *( #{m.my_variable_name}.begin() ) = #{m.element_name_for_cpp.uncapitalize};" << "\n" -code << " #{m.is_first_added_variable} = true;" << "\n" -code << " }" << "\n" -code << " else" << "\n" -code << " {" << "\n" -code << " #{m.my_variable_name}.push_back( #{m.element_name_for_cpp.uncapitalize} );" << "\n" -code << " #{m.is_first_added_variable} = true;" << "\n" -code << " }" << "\n" - elsif m.is_required -code << " #{m.is_found_variable} = true;" << "\n" -code << " isSuccess &= #{m.my_variable_name}->fromXElement( message, *it );" << "\n" - else -code << " myHas#{m.element_name_for_cpp} = true;" << "\n" -code << " isSuccess &= #{m.my_variable_name}->fromXElement( message, *it );" << "\n" - end - code << tab << tab << tab << tab << "}" << "\n" -end -code << tab << tab << tab << tab << "else" << "\n" -code << tab << tab << tab << tab << "{" << "\n" - -members.each do |m| - if m.is_required -code << " if( !#{m.is_found_variable} )" << "\n" -code << " {" << "\n" -code << " isSuccess = false;" << "\n" -code << " message << \"#{group_class_name}: '#{m.element_name}' element is required but was not found\" << std::endl;" << "\n" -code << " }" << "\n" - end -end -code << " break;" << "\n" -code << tab << tab << tab << tab << "}" << "\n" -code << tab << tab << tab << "}" << "\n" -code << tab << tab << tab << "return isSuccess;" << "\n" -code << tab << tab << "}" << "\n" - -puts code.string \ No newline at end of file diff --git a/gen/version-a/cueNoteGroup.rb b/gen/version-a/cueNoteGroup.rb deleted file mode 100755 index d0633d863..000000000 --- a/gen/version-a/cueNoteGroup.rb +++ /dev/null @@ -1,131 +0,0 @@ - -require 'stringio' - -class String - def uncapitalize - self[0, 1].downcase + self[1..-1] - end -end - -class Member - attr_accessor :my_variable_name - attr_accessor :element_name - attr_accessor :is_set - attr_accessor :is_required - attr_accessor :element_name_for_cpp - - def initialize in_my_variable_name, in_element_name, in_description, in_element_name_for_cpp - @my_variable_name = in_my_variable_name - @element_name = in_element_name - @element_name_for_cpp = in_element_name_for_cpp - - if in_description.eql? "collection" - @is_set = true - @is_required = false - elsif in_description.eql? "required" - @is_set = false - @is_required = true - elsif in_description.eql? "optional" - @is_set = false - @is_required = false - else - @is_set = false - @is_required = false - end - end - - def is_found_variable - "is#{element_name_for_cpp}Found" - end - - def is_first_added_variable - "isFirst#{element_name_for_cpp}Added" - end - -end - -=begin -example_required_single = Member.new "myCreditWords", "credit-words", "required", "CreditWords" -example_optional_single = Member.new "myOptionalThing", "optional-thing", "optional", "OptionalThing" -example_collection = Member.new "myCatSet", "cat", "collection", "Cat" -=end - -group_class_name = "CueNoteGroup" - -members = [] - -#sample code -members << Member.new( "myCue", "cue", "required", "Cue" ) -members << Member.new( "myFullNoteGroup", "TODO fix this", "required", "FullNoteGroup" ) -members << Member.new( "myDuration", "duration", "required", "Duration" ) - -code = StringIO.new -tab = " " -code << tab << tab << "bool #{group_class_name}::fromXElement( std::ostream& message, xml::XElement& xelement )" << "\n" -code << tab << tab << "{" << "\n" -code << tab << tab << tab << "bool isSuccess = true;" << "\n" - -members.each do |m| - if m.is_required && !m.is_set - code << tab << tab << tab << "bool #{m.is_found_variable} = false;" << "\n" - elsif m.is_set - code << tab << tab << tab << "bool #{m.is_first_added_variable} = false;" << "\n" - end -end -code << "\n" -code << tab << tab << tab << "for( auto it = xelement.elementsBegin(); it != xelement.elementsEnd(); ++it )" << "\n" -code << tab << tab << tab << "{" << "\n" -code << tab << tab << tab << tab << "const std::string elementName = it->getName();" << "\n" -code << "\n" -first_if = true -members.each do |m| - - code << tab << tab << tab << tab - if !first_if - code << "else " - end - first_if = false - code << "if( elementName == \"#{m.element_name}\" )" << "\n" - code << tab << tab << tab << tab << "{" << "\n" - if m.is_set -code << " auto #{m.element_name_for_cpp.uncapitalize} = make#{m.element_name_for_cpp}();" << "\n" -code << " isSuccess &= #{m.element_name_for_cpp.uncapitalize}->fromXElement( message, *it );" << "\n" -code << "\n" -code << " if( !#{m.is_first_added_variable} && #{m.my_variable_name}.size() == 1 )" << "\n" -code << " {" << "\n" -code << " *( #{m.my_variable_name}.begin() ) = #{m.element_name_for_cpp.uncapitalize};" << "\n" -code << " #{m.is_first_added_variable} = true;" << "\n" -code << " }" << "\n" -code << " else" << "\n" -code << " {" << "\n" -code << " #{m.my_variable_name}.push_back( #{m.element_name_for_cpp.uncapitalize} );" << "\n" -code << " #{m.is_first_added_variable} = true;" << "\n" -code << " }" << "\n" - elsif m.is_required -code << " #{m.is_found_variable} = true;" << "\n" -code << " isSuccess &= #{m.my_variable_name}->fromXElement( message, *it );" << "\n" - else -code << " myHas#{m.element_name_for_cpp} = true;" << "\n" -code << " isSuccess &= #{m.my_variable_name}->fromXElement( message, *it );" << "\n" - end - code << tab << tab << tab << tab << "}" << "\n" -end -code << tab << tab << tab << tab << "else" << "\n" -code << tab << tab << tab << tab << "{" << "\n" - -members.each do |m| - if m.is_required -code << " if( !#{m.is_found_variable} )" << "\n" -code << " {" << "\n" -code << " isSuccess = false;" << "\n" -code << " message << \"#{group_class_name}: '#{m.element_name}' element is required but was not found\" << std::endl;" << "\n" -code << " }" << "\n" - end -end -code << " break;" << "\n" -code << tab << tab << tab << tab << "}" << "\n" -code << tab << tab << tab << "}" << "\n" -code << tab << tab << tab << "return isSuccess;" << "\n" -code << tab << tab << "}" << "\n" - -puts code.string \ No newline at end of file diff --git a/gen/version-a/displayStepOctaveGroup.rb b/gen/version-a/displayStepOctaveGroup.rb deleted file mode 100755 index a39c6c57e..000000000 --- a/gen/version-a/displayStepOctaveGroup.rb +++ /dev/null @@ -1,130 +0,0 @@ - -require 'stringio' - -class String - def uncapitalize - self[0, 1].downcase + self[1..-1] - end -end - -class Member - attr_accessor :my_variable_name - attr_accessor :element_name - attr_accessor :is_set - attr_accessor :is_required - attr_accessor :element_name_for_cpp - - def initialize in_my_variable_name, in_element_name, in_description, in_element_name_for_cpp - @my_variable_name = in_my_variable_name - @element_name = in_element_name - @element_name_for_cpp = in_element_name_for_cpp - - if in_description.eql? "collection" - @is_set = true - @is_required = false - elsif in_description.eql? "required" - @is_set = false - @is_required = true - elsif in_description.eql? "optional" - @is_set = false - @is_required = false - else - @is_set = false - @is_required = false - end - end - - def is_found_variable - "is#{element_name_for_cpp}Found" - end - - def is_first_added_variable - "isFirst#{element_name_for_cpp}Added" - end - -end - -=begin -example_required_single = Member.new "myCreditWords", "credit-words", "required", "CreditWords" -example_optional_single = Member.new "myOptionalThing", "optional-thing", "optional", "OptionalThing" -example_collection = Member.new "myCatSet", "cat", "collection", "Cat" -=end - -group_class_name = "EditorialGroup" - -members = [] - -#sample code -members << Member.new( "myFootnote", "display-step", "optional", "DisplayStep" ) -members << Member.new( "myLevel", "display-step", "required", "DisplayStep" ) - -code = StringIO.new -tab = " " -code << tab << tab << "bool #{group_class_name}::fromXElement( std::ostream& message, xml::XElement& xelement )" << "\n" -code << tab << tab << "{" << "\n" -code << tab << tab << tab << "bool isSuccess = true;" << "\n" - -members.each do |m| - if m.is_required && !m.is_set - code << tab << tab << tab << "bool #{m.is_found_variable} = false;" << "\n" - elsif m.is_set - code << tab << tab << tab << "bool #{m.is_first_added_variable} = false;" << "\n" - end -end -code << "\n" -code << tab << tab << tab << "for( auto it = xelement.elementsBegin(); it != xelement.elementsEnd(); ++it )" << "\n" -code << tab << tab << tab << "{" << "\n" -code << tab << tab << tab << tab << "const std::string elementName = it->getName();" << "\n" -code << "\n" -first_if = true -members.each do |m| - - code << tab << tab << tab << tab - if !first_if - code << "else " - end - first_if = false - code << "if( elementName == \"#{m.element_name}\" )" << "\n" - code << tab << tab << tab << tab << "{" << "\n" - if m.is_set -code << " auto #{m.element_name_for_cpp.uncapitalize} = make#{m.element_name_for_cpp}();" << "\n" -code << " isSuccess &= #{m.element_name_for_cpp.uncapitalize}->fromXElement( message, *it );" << "\n" -code << "\n" -code << " if( !#{m.is_first_added_variable} && #{m.my_variable_name}.size() == 1 )" << "\n" -code << " {" << "\n" -code << " *( #{m.my_variable_name}.begin() ) = #{m.element_name_for_cpp.uncapitalize};" << "\n" -code << " #{m.is_first_added_variable} = true;" << "\n" -code << " }" << "\n" -code << " else" << "\n" -code << " {" << "\n" -code << " #{m.my_variable_name}.push_back( #{m.element_name_for_cpp.uncapitalize} );" << "\n" -code << " #{m.is_first_added_variable} = true;" << "\n" -code << " }" << "\n" - elsif m.is_required -code << " #{m.is_found_variable} = true;" << "\n" -code << " isSuccess &= #{m.my_variable_name}->fromXElement( message, *it );" << "\n" - else -code << " myHas#{m.element_name_for_cpp} = true;" << "\n" -code << " isSuccess &= #{m.my_variable_name}->fromXElement( message, *it );" << "\n" - end - code << tab << tab << tab << tab << "}" << "\n" -end -code << tab << tab << tab << tab << "else" << "\n" -code << tab << tab << tab << tab << "{" << "\n" - -members.each do |m| - if m.is_required -code << " if( !#{m.is_found_variable} )" << "\n" -code << " {" << "\n" -code << " isSuccess = false;" << "\n" -code << " message << \"#{group_class_name}: '#{m.element_name}' element is required but was not found\" << std::endl;" << "\n" -code << " }" << "\n" - end -end -code << " break;" << "\n" -code << tab << tab << tab << tab << "}" << "\n" -code << tab << tab << tab << "}" << "\n" -code << tab << tab << tab << "return isSuccess;" << "\n" -code << tab << tab << "}" << "\n" - -puts code.string \ No newline at end of file diff --git a/gen/version-a/editorialGroup.rb b/gen/version-a/editorialGroup.rb deleted file mode 100755 index 1adb396fb..000000000 --- a/gen/version-a/editorialGroup.rb +++ /dev/null @@ -1,130 +0,0 @@ - -require 'stringio' - -class String - def uncapitalize - self[0, 1].downcase + self[1..-1] - end -end - -class Member - attr_accessor :my_variable_name - attr_accessor :element_name - attr_accessor :is_set - attr_accessor :is_required - attr_accessor :element_name_for_cpp - - def initialize in_my_variable_name, in_element_name, in_description, in_element_name_for_cpp - @my_variable_name = in_my_variable_name - @element_name = in_element_name - @element_name_for_cpp = in_element_name_for_cpp - - if in_description.eql? "collection" - @is_set = true - @is_required = false - elsif in_description.eql? "required" - @is_set = false - @is_required = true - elsif in_description.eql? "optional" - @is_set = false - @is_required = false - else - @is_set = false - @is_required = false - end - end - - def is_found_variable - "is#{element_name_for_cpp}Found" - end - - def is_first_added_variable - "isFirst#{element_name_for_cpp}Added" - end - -end - -=begin -example_required_single = Member.new "myCreditWords", "credit-words", "required", "CreditWords" -example_optional_single = Member.new "myOptionalThing", "optional-thing", "optional", "OptionalThing" -example_collection = Member.new "myCatSet", "cat", "collection", "Cat" -=end - -group_class_name = "EditorialGroup" - -members = [] - -#sample code -members << Member.new( "myFootnote", "footnote", "optional", "Footnote" ) -members << Member.new( "myLevel", "level", "optional", "Level" ) - -code = StringIO.new -tab = " " -code << tab << tab << "bool #{group_class_name}::fromXElement( std::ostream& message, xml::XElement& xelement )" << "\n" -code << tab << tab << "{" << "\n" -code << tab << tab << tab << "bool isSuccess = true;" << "\n" - -members.each do |m| - if m.is_required && !m.is_set - code << tab << tab << tab << "bool #{m.is_found_variable} = false;" << "\n" - elsif m.is_set - code << tab << tab << tab << "bool #{m.is_first_added_variable} = false;" << "\n" - end -end -code << "\n" -code << tab << tab << tab << "for( auto it = xelement.elementsBegin(); it != xelement.elementsEnd(); ++it )" << "\n" -code << tab << tab << tab << "{" << "\n" -code << tab << tab << tab << tab << "const std::string elementName = it->getName();" << "\n" -code << "\n" -first_if = true -members.each do |m| - - code << tab << tab << tab << tab - if !first_if - code << "else " - end - first_if = false - code << "if( elementName == \"#{m.element_name}\" )" << "\n" - code << tab << tab << tab << tab << "{" << "\n" - if m.is_set -code << " auto #{m.element_name_for_cpp.uncapitalize} = make#{m.element_name_for_cpp}();" << "\n" -code << " isSuccess &= #{m.element_name_for_cpp.uncapitalize}->fromXElement( message, *it );" << "\n" -code << "\n" -code << " if( !#{m.is_first_added_variable} && #{m.my_variable_name}.size() == 1 )" << "\n" -code << " {" << "\n" -code << " *( #{m.my_variable_name}.begin() ) = #{m.element_name_for_cpp.uncapitalize};" << "\n" -code << " #{m.is_first_added_variable} = true;" << "\n" -code << " }" << "\n" -code << " else" << "\n" -code << " {" << "\n" -code << " #{m.my_variable_name}.push_back( #{m.element_name_for_cpp.uncapitalize} );" << "\n" -code << " #{m.is_first_added_variable} = true;" << "\n" -code << " }" << "\n" - elsif m.is_required -code << " #{m.is_found_variable} = true;" << "\n" -code << " isSuccess &= #{m.my_variable_name}->fromXElement( message, *it );" << "\n" - else -code << " myHas#{m.element_name_for_cpp} = true;" << "\n" -code << " isSuccess &= #{m.my_variable_name}->fromXElement( message, *it );" << "\n" - end - code << tab << tab << tab << tab << "}" << "\n" -end -code << tab << tab << tab << tab << "else" << "\n" -code << tab << tab << tab << tab << "{" << "\n" - -members.each do |m| - if m.is_required -code << " if( !#{m.is_found_variable} )" << "\n" -code << " {" << "\n" -code << " isSuccess = false;" << "\n" -code << " message << \"#{group_class_name}: '#{m.element_name}' element is required but was not found\" << std::endl;" << "\n" -code << " }" << "\n" - end -end -code << " break;" << "\n" -code << tab << tab << tab << tab << "}" << "\n" -code << tab << tab << tab << "}" << "\n" -code << tab << tab << tab << "return isSuccess;" << "\n" -code << tab << tab << "}" << "\n" - -puts code.string \ No newline at end of file diff --git a/gen/version-a/editorialVoiceDirectionGroup.rb b/gen/version-a/editorialVoiceDirectionGroup.rb deleted file mode 100755 index 993d7088d..000000000 --- a/gen/version-a/editorialVoiceDirectionGroup.rb +++ /dev/null @@ -1,131 +0,0 @@ - -require 'stringio' - -class String - def uncapitalize - self[0, 1].downcase + self[1..-1] - end -end - -class Member - attr_accessor :my_variable_name - attr_accessor :element_name - attr_accessor :is_set - attr_accessor :is_required - attr_accessor :element_name_for_cpp - - def initialize in_my_variable_name, in_element_name, in_description, in_element_name_for_cpp - @my_variable_name = in_my_variable_name - @element_name = in_element_name - @element_name_for_cpp = in_element_name_for_cpp - - if in_description.eql? "collection" - @is_set = true - @is_required = false - elsif in_description.eql? "required" - @is_set = false - @is_required = true - elsif in_description.eql? "optional" - @is_set = false - @is_required = false - else - @is_set = false - @is_required = false - end - end - - def is_found_variable - "is#{element_name_for_cpp}Found" - end - - def is_first_added_variable - "isFirst#{element_name_for_cpp}Added" - end - -end - -=begin -example_required_single = Member.new "myCreditWords", "credit-words", "required", "CreditWords" -example_optional_single = Member.new "myOptionalThing", "optional-thing", "optional", "OptionalThing" -example_collection = Member.new "myCatSet", "cat", "collection", "Cat" -=end - -group_class_name = "EditorialVoiceDirectionGroup" - -members = [] - -#sample code -members << Member.new( "myFootnote", "footnote", "optional", "Footnote" ) -members << Member.new( "myLevel", "level", "optional", "Level" ) -members << Member.new( "myVoice", "voice", "optional", "Voice" ) - -code = StringIO.new -tab = " " -code << tab << tab << "bool #{group_class_name}::fromXElement( std::ostream& message, xml::XElement& xelement )" << "\n" -code << tab << tab << "{" << "\n" -code << tab << tab << tab << "bool isSuccess = true;" << "\n" - -members.each do |m| - if m.is_required && !m.is_set - code << tab << tab << tab << "bool #{m.is_found_variable} = false;" << "\n" - elsif m.is_set - code << tab << tab << tab << "bool #{m.is_first_added_variable} = false;" << "\n" - end -end -code << "\n" -code << tab << tab << tab << "for( auto it = xelement.elementsBegin(); it != xelement.elementsEnd(); ++it )" << "\n" -code << tab << tab << tab << "{" << "\n" -code << tab << tab << tab << tab << "const std::string elementName = it->getName();" << "\n" -code << "\n" -first_if = true -members.each do |m| - - code << tab << tab << tab << tab - if !first_if - code << "else " - end - first_if = false - code << "if( elementName == \"#{m.element_name}\" )" << "\n" - code << tab << tab << tab << tab << "{" << "\n" - if m.is_set -code << " auto #{m.element_name_for_cpp.uncapitalize} = make#{m.element_name_for_cpp}();" << "\n" -code << " isSuccess &= #{m.element_name_for_cpp.uncapitalize}->fromXElement( message, *it );" << "\n" -code << "\n" -code << " if( !#{m.is_first_added_variable} && #{m.my_variable_name}.size() == 1 )" << "\n" -code << " {" << "\n" -code << " *( #{m.my_variable_name}.begin() ) = #{m.element_name_for_cpp.uncapitalize};" << "\n" -code << " #{m.is_first_added_variable} = true;" << "\n" -code << " }" << "\n" -code << " else" << "\n" -code << " {" << "\n" -code << " #{m.my_variable_name}.push_back( #{m.element_name_for_cpp.uncapitalize} );" << "\n" -code << " #{m.is_first_added_variable} = true;" << "\n" -code << " }" << "\n" - elsif m.is_required -code << " #{m.is_found_variable} = true;" << "\n" -code << " isSuccess &= #{m.my_variable_name}->fromXElement( message, *it );" << "\n" - else -code << " myHas#{m.element_name_for_cpp} = true;" << "\n" -code << " isSuccess &= #{m.my_variable_name}->fromXElement( message, *it );" << "\n" - end - code << tab << tab << tab << tab << "}" << "\n" -end -code << tab << tab << tab << tab << "else" << "\n" -code << tab << tab << tab << tab << "{" << "\n" - -members.each do |m| - if m.is_required -code << " if( !#{m.is_found_variable} )" << "\n" -code << " {" << "\n" -code << " isSuccess = false;" << "\n" -code << " message << \"#{group_class_name}: '#{m.element_name}' element is required but was not found\" << std::endl;" << "\n" -code << " }" << "\n" - end -end -code << " break;" << "\n" -code << tab << tab << tab << tab << "}" << "\n" -code << tab << tab << tab << "}" << "\n" -code << tab << tab << tab << "return isSuccess;" << "\n" -code << tab << tab << "}" << "\n" - -puts code.string \ No newline at end of file diff --git a/gen/version-a/editorialVoiceGroup.rb b/gen/version-a/editorialVoiceGroup.rb deleted file mode 100755 index dc6b6a469..000000000 --- a/gen/version-a/editorialVoiceGroup.rb +++ /dev/null @@ -1,131 +0,0 @@ - -require 'stringio' - -class String - def uncapitalize - self[0, 1].downcase + self[1..-1] - end -end - -class Member - attr_accessor :my_variable_name - attr_accessor :element_name - attr_accessor :is_set - attr_accessor :is_required - attr_accessor :element_name_for_cpp - - def initialize in_my_variable_name, in_element_name, in_description, in_element_name_for_cpp - @my_variable_name = in_my_variable_name - @element_name = in_element_name - @element_name_for_cpp = in_element_name_for_cpp - - if in_description.eql? "collection" - @is_set = true - @is_required = false - elsif in_description.eql? "required" - @is_set = false - @is_required = true - elsif in_description.eql? "optional" - @is_set = false - @is_required = false - else - @is_set = false - @is_required = false - end - end - - def is_found_variable - "is#{element_name_for_cpp}Found" - end - - def is_first_added_variable - "isFirst#{element_name_for_cpp}Added" - end - -end - -=begin -example_required_single = Member.new "myCreditWords", "credit-words", "required", "CreditWords" -example_optional_single = Member.new "myOptionalThing", "optional-thing", "optional", "OptionalThing" -example_collection = Member.new "myCatSet", "cat", "collection", "Cat" -=end - -group_class_name = "EditorialVoiceGroup" - -members = [] - -#sample code -members << Member.new( "myFootnote", "footnote", "optional", "Footnote" ) -members << Member.new( "myLevel", "level", "optional", "Level" ) -members << Member.new( "myVoice", "voice", "optional", "Voice" ) - -code = StringIO.new -tab = " " -code << tab << tab << "bool #{group_class_name}::fromXElement( std::ostream& message, xml::XElement& xelement )" << "\n" -code << tab << tab << "{" << "\n" -code << tab << tab << tab << "bool isSuccess = true;" << "\n" - -members.each do |m| - if m.is_required && !m.is_set - code << tab << tab << tab << "bool #{m.is_found_variable} = false;" << "\n" - elsif m.is_set - code << tab << tab << tab << "bool #{m.is_first_added_variable} = false;" << "\n" - end -end -code << "\n" -code << tab << tab << tab << "for( auto it = xelement.elementsBegin(); it != xelement.elementsEnd(); ++it )" << "\n" -code << tab << tab << tab << "{" << "\n" -code << tab << tab << tab << tab << "const std::string elementName = it->getName();" << "\n" -code << "\n" -first_if = true -members.each do |m| - - code << tab << tab << tab << tab - if !first_if - code << "else " - end - first_if = false - code << "if( elementName == \"#{m.element_name}\" )" << "\n" - code << tab << tab << tab << tab << "{" << "\n" - if m.is_set -code << " auto #{m.element_name_for_cpp.uncapitalize} = make#{m.element_name_for_cpp}();" << "\n" -code << " isSuccess &= #{m.element_name_for_cpp.uncapitalize}->fromXElement( message, *it );" << "\n" -code << "\n" -code << " if( !#{m.is_first_added_variable} && #{m.my_variable_name}.size() == 1 )" << "\n" -code << " {" << "\n" -code << " *( #{m.my_variable_name}.begin() ) = #{m.element_name_for_cpp.uncapitalize};" << "\n" -code << " #{m.is_first_added_variable} = true;" << "\n" -code << " }" << "\n" -code << " else" << "\n" -code << " {" << "\n" -code << " #{m.my_variable_name}.push_back( #{m.element_name_for_cpp.uncapitalize} );" << "\n" -code << " #{m.is_first_added_variable} = true;" << "\n" -code << " }" << "\n" - elsif m.is_required -code << " #{m.is_found_variable} = true;" << "\n" -code << " isSuccess &= #{m.my_variable_name}->fromXElement( message, *it );" << "\n" - else -code << " myHas#{m.element_name_for_cpp} = true;" << "\n" -code << " isSuccess &= #{m.my_variable_name}->fromXElement( message, *it );" << "\n" - end - code << tab << tab << tab << tab << "}" << "\n" -end -code << tab << tab << tab << tab << "else" << "\n" -code << tab << tab << tab << tab << "{" << "\n" - -members.each do |m| - if m.is_required -code << " if( !#{m.is_found_variable} )" << "\n" -code << " {" << "\n" -code << " isSuccess = false;" << "\n" -code << " message << \"#{group_class_name}: '#{m.element_name}' element is required but was not found\" << std::endl;" << "\n" -code << " }" << "\n" - end -end -code << " break;" << "\n" -code << tab << tab << tab << tab << "}" << "\n" -code << tab << tab << tab << "}" << "\n" -code << tab << tab << tab << "return isSuccess;" << "\n" -code << tab << tab << "}" << "\n" - -puts code.string \ No newline at end of file diff --git a/gen/version-a/elementsHUsingFile.rb b/gen/version-a/elementsHUsingFile.rb deleted file mode 100755 index 693c7566b..000000000 --- a/gen/version-a/elementsHUsingFile.rb +++ /dev/null @@ -1,28 +0,0 @@ - - -def elementsHUsingFile( alias_symbol, actual_symbol ) - # one off stupid files for using statements - File.open("../../src/mx/core/elements/#{alias_symbol}.h", "w") do |stupid_one_off_file| - stupid_one_off_file << "// MusicXML Class Library v0.1.1" << "\n" - stupid_one_off_file << "// Copyright (c) 2015 - 2016 by Matthew James Briggs" << "\n" - stupid_one_off_file << "" << "\n" - stupid_one_off_file << "#pragma once" << "\n" - stupid_one_off_file << "#include \"mx/core/elements/#{actual_symbol}.h\"" << "\n" - stupid_one_off_file << "" << "\n" - stupid_one_off_file << "namespace mx" << "\n" - stupid_one_off_file << "{" << "\n" - stupid_one_off_file << " namespace core" << "\n" - stupid_one_off_file << " {" << "\n" - stupid_one_off_file << "" << "\n" - stupid_one_off_file << " using #{alias_symbol} = #{actual_symbol};\n" - stupid_one_off_file << " using #{alias_symbol}Ptr = std::shared_ptr<#{alias_symbol}>;\n" - stupid_one_off_file << " using #{alias_symbol}UPtr = std::unique_ptr<#{alias_symbol}>;\n" - stupid_one_off_file << " using #{alias_symbol}Set = std::vector<#{alias_symbol}Ptr>;\n" - stupid_one_off_file << " using #{alias_symbol}SetIter = #{alias_symbol}Set::iterator;\n" - stupid_one_off_file << " using #{alias_symbol}SetIterConst = #{alias_symbol}Set::const_iterator;\n" - stupid_one_off_file << " inline #{alias_symbol}Ptr make#{alias_symbol}() { return std::make_shared<#{alias_symbol}>(); }\n" - stupid_one_off_file << " }" << "\n" - stupid_one_off_file << "}" << "\n" - end - -end \ No newline at end of file diff --git a/gen/version-a/elisionSyllabicGroup.rb b/gen/version-a/elisionSyllabicGroup.rb deleted file mode 100755 index f1058f4e2..000000000 --- a/gen/version-a/elisionSyllabicGroup.rb +++ /dev/null @@ -1,130 +0,0 @@ - -require 'stringio' - -class String - def uncapitalize - self[0, 1].downcase + self[1..-1] - end -end - -class Member - attr_accessor :my_variable_name - attr_accessor :element_name - attr_accessor :is_set - attr_accessor :is_required - attr_accessor :element_name_for_cpp - - def initialize in_my_variable_name, in_element_name, in_description, in_element_name_for_cpp - @my_variable_name = in_my_variable_name - @element_name = in_element_name - @element_name_for_cpp = in_element_name_for_cpp - - if in_description.eql? "collection" - @is_set = true - @is_required = false - elsif in_description.eql? "required" - @is_set = false - @is_required = true - elsif in_description.eql? "optional" - @is_set = false - @is_required = false - else - @is_set = false - @is_required = false - end - end - - def is_found_variable - "is#{element_name_for_cpp}Found" - end - - def is_first_added_variable - "isFirst#{element_name_for_cpp}Added" - end - -end - -=begin -example_required_single = Member.new "myCreditWords", "credit-words", "required", "CreditWords" -example_optional_single = Member.new "myOptionalThing", "optional-thing", "optional", "OptionalThing" -example_collection = Member.new "myCatSet", "cat", "collection", "Cat" -=end - -group_class_name = "ElisionSyllabicGroup" - -members = [] - -#sample code -members << Member.new( "myElision", "elision", "required", "Elision" ) -members << Member.new( "mySyllabic", "syllabic", "optional", "Syllabic" ) - -code = StringIO.new -tab = " " -code << tab << tab << "bool #{group_class_name}::fromXElement( std::ostream& message, xml::XElement& xelement )" << "\n" -code << tab << tab << "{" << "\n" -code << tab << tab << tab << "bool isSuccess = true;" << "\n" - -members.each do |m| - if m.is_required && !m.is_set - code << tab << tab << tab << "bool #{m.is_found_variable} = false;" << "\n" - elsif m.is_set - code << tab << tab << tab << "bool #{m.is_first_added_variable} = false;" << "\n" - end -end -code << "\n" -code << tab << tab << tab << "for( auto it = xelement.elementsBegin(); it != xelement.elementsEnd(); ++it )" << "\n" -code << tab << tab << tab << "{" << "\n" -code << tab << tab << tab << tab << "const std::string elementName = it->getName();" << "\n" -code << "\n" -first_if = true -members.each do |m| - - code << tab << tab << tab << tab - if !first_if - code << "else " - end - first_if = false - code << "if( elementName == \"#{m.element_name}\" )" << "\n" - code << tab << tab << tab << tab << "{" << "\n" - if m.is_set -code << " auto #{m.element_name_for_cpp.uncapitalize} = make#{m.element_name_for_cpp}();" << "\n" -code << " isSuccess &= #{m.element_name_for_cpp.uncapitalize}->fromXElement( message, *it );" << "\n" -code << "\n" -code << " if( !#{m.is_first_added_variable} && #{m.my_variable_name}.size() == 1 )" << "\n" -code << " {" << "\n" -code << " *( #{m.my_variable_name}.begin() ) = #{m.element_name_for_cpp.uncapitalize};" << "\n" -code << " #{m.is_first_added_variable} = true;" << "\n" -code << " }" << "\n" -code << " else" << "\n" -code << " {" << "\n" -code << " #{m.my_variable_name}.push_back( #{m.element_name_for_cpp.uncapitalize} );" << "\n" -code << " #{m.is_first_added_variable} = true;" << "\n" -code << " }" << "\n" - elsif m.is_required -code << " #{m.is_found_variable} = true;" << "\n" -code << " isSuccess &= #{m.my_variable_name}->fromXElement( message, *it );" << "\n" - else -code << " myHas#{m.element_name_for_cpp} = true;" << "\n" -code << " isSuccess &= #{m.my_variable_name}->fromXElement( message, *it );" << "\n" - end - code << tab << tab << tab << tab << "}" << "\n" -end -code << tab << tab << tab << tab << "else" << "\n" -code << tab << tab << tab << tab << "{" << "\n" - -members.each do |m| - if m.is_required -code << " if( !#{m.is_found_variable} )" << "\n" -code << " {" << "\n" -code << " isSuccess = false;" << "\n" -code << " message << \"#{group_class_name}: '#{m.element_name}' element is required but was not found\" << std::endl;" << "\n" -code << " }" << "\n" - end -end -code << " break;" << "\n" -code << tab << tab << tab << tab << "}" << "\n" -code << tab << tab << tab << "}" << "\n" -code << tab << tab << tab << "return isSuccess;" << "\n" -code << tab << tab << "}" << "\n" - -puts code.string \ No newline at end of file diff --git a/gen/version-a/elisionSyllabicTextGroup.rb b/gen/version-a/elisionSyllabicTextGroup.rb deleted file mode 100755 index a7f349387..000000000 --- a/gen/version-a/elisionSyllabicTextGroup.rb +++ /dev/null @@ -1,130 +0,0 @@ - -require 'stringio' - -class String - def uncapitalize - self[0, 1].downcase + self[1..-1] - end -end - -class Member - attr_accessor :my_variable_name - attr_accessor :element_name - attr_accessor :is_set - attr_accessor :is_required - attr_accessor :element_name_for_cpp - - def initialize in_my_variable_name, in_element_name, in_description, in_element_name_for_cpp - @my_variable_name = in_my_variable_name - @element_name = in_element_name - @element_name_for_cpp = in_element_name_for_cpp - - if in_description.eql? "collection" - @is_set = true - @is_required = false - elsif in_description.eql? "required" - @is_set = false - @is_required = true - elsif in_description.eql? "optional" - @is_set = false - @is_required = false - else - @is_set = false - @is_required = false - end - end - - def is_found_variable - "is#{element_name_for_cpp}Found" - end - - def is_first_added_variable - "isFirst#{element_name_for_cpp}Added" - end - -end - -=begin -example_required_single = Member.new "myCreditWords", "credit-words", "required", "CreditWords" -example_optional_single = Member.new "myOptionalThing", "optional-thing", "optional", "OptionalThing" -example_collection = Member.new "myCatSet", "cat", "collection", "Cat" -=end - -group_class_name = "ElisionSyllabicTextGroup" - -members = [] - -#sample code -members << Member.new( "myElisionSyllabicGroup", "", "optional", "ElisionSyllabicGroup" ) -members << Member.new( "myText", "text", "required", "Text" ) - -code = StringIO.new -tab = " " -code << tab << tab << "bool #{group_class_name}::fromXElement( std::ostream& message, xml::XElement& xelement )" << "\n" -code << tab << tab << "{" << "\n" -code << tab << tab << tab << "bool isSuccess = true;" << "\n" - -members.each do |m| - if m.is_required && !m.is_set - code << tab << tab << tab << "bool #{m.is_found_variable} = false;" << "\n" - elsif m.is_set - code << tab << tab << tab << "bool #{m.is_first_added_variable} = false;" << "\n" - end -end -code << "\n" -code << tab << tab << tab << "for( auto it = xelement.elementsBegin(); it != xelement.elementsEnd(); ++it )" << "\n" -code << tab << tab << tab << "{" << "\n" -code << tab << tab << tab << tab << "const std::string elementName = it->getName();" << "\n" -code << "\n" -first_if = true -members.each do |m| - - code << tab << tab << tab << tab - if !first_if - code << "else " - end - first_if = false - code << "if( elementName == \"#{m.element_name}\" )" << "\n" - code << tab << tab << tab << tab << "{" << "\n" - if m.is_set -code << " auto #{m.element_name_for_cpp.uncapitalize} = make#{m.element_name_for_cpp}();" << "\n" -code << " isSuccess &= #{m.element_name_for_cpp.uncapitalize}->fromXElement( message, *it );" << "\n" -code << "\n" -code << " if( !#{m.is_first_added_variable} && #{m.my_variable_name}.size() == 1 )" << "\n" -code << " {" << "\n" -code << " *( #{m.my_variable_name}.begin() ) = #{m.element_name_for_cpp.uncapitalize};" << "\n" -code << " #{m.is_first_added_variable} = true;" << "\n" -code << " }" << "\n" -code << " else" << "\n" -code << " {" << "\n" -code << " #{m.my_variable_name}.push_back( #{m.element_name_for_cpp.uncapitalize} );" << "\n" -code << " #{m.is_first_added_variable} = true;" << "\n" -code << " }" << "\n" - elsif m.is_required -code << " #{m.is_found_variable} = true;" << "\n" -code << " isSuccess &= #{m.my_variable_name}->fromXElement( message, *it );" << "\n" - else -code << " myHas#{m.element_name_for_cpp} = true;" << "\n" -code << " isSuccess &= #{m.my_variable_name}->fromXElement( message, *it );" << "\n" - end - code << tab << tab << tab << tab << "}" << "\n" -end -code << tab << tab << tab << tab << "else" << "\n" -code << tab << tab << tab << tab << "{" << "\n" - -members.each do |m| - if m.is_required -code << " if( !#{m.is_found_variable} )" << "\n" -code << " {" << "\n" -code << " isSuccess = false;" << "\n" -code << " message << \"#{group_class_name}: '#{m.element_name}' element is required but was not found\" << std::endl;" << "\n" -code << " }" << "\n" - end -end -code << " break;" << "\n" -code << tab << tab << tab << tab << "}" << "\n" -code << tab << tab << tab << "}" << "\n" -code << tab << tab << tab << "return isSuccess;" << "\n" -code << tab << tab << "}" << "\n" - -puts code.string \ No newline at end of file diff --git a/gen/version-a/findFilesWithBadCopyright.rb b/gen/version-a/findFilesWithBadCopyright.rb deleted file mode 100755 index ea7bee13b..000000000 --- a/gen/version-a/findFilesWithBadCopyright.rb +++ /dev/null @@ -1,111 +0,0 @@ -expected_identifier = "// MusicXML Class Library v0.2" -expected_copyright = "// Copyright (c) 2015 - 2016 by Matthew James Briggs" - -new_identifier = "// MusicXML Class Library v0.3.0" -new_copyright = "// Copyright (c) 2015 - 2016 by Matthew James Briggs" - -def regexify input_string - input_string.gsub!('/','\/') - input_string.gsub!(' ','\s') - input_string.gsub!('(','\(') - input_string.gsub!(')','\)') - input_string.gsub!('[','\[') - input_string.gsub!(']','\]') - input_string.gsub!('-','\-') -end - -regexify expected_identifier -regexify expected_copyright - -directories = [ - "../../src/mx/core", - "../../src/mx/core/elements", - "../../src/mx/xml", - "../../src/mx/utility", - "../../src/mxtest/utility", - "../../src/mxtest/core", - "../../src/mxtest/xml", - "../../src/mxtest/control", - "../../src/mxtest/import" -] - -bad_files = [] - -# CHECK ALL OF THE FILES ################################################################ - -directories.each do |dir| - drectory_with_star = "#{dir}/*" - Dir[drectory_with_star].each do |item| - next if item == '.' or item == '..' or item == ".DS_Store" or File.directory?(item) - filename = "#{item}" - #puts filename - lines = [] - - File.open(filename, "r") do |input_file| - input_file.each_line do |line| - lines << line - end - end - - rx = /#{expected_identifier}/ - is_first_line_correct = ( ( lines[0] =~ rx ) != nil ) - - rx = /#{expected_copyright}/ - is_second_line_correct = ( ( lines[1] =~ rx ) != nil ) - - if ( !is_first_line_correct ) || ( !is_second_line_correct ) - bad_files << filename - end # if - - end # foreach file - -end # foreach dir - -# ABORT IF UNEXPECTED STRINGS EXIST OUT THERE ########################################## - -bad_files.each do |bad_file| - puts "subl #{bad_file}" -end - -if bad_files.length > 0 - abort("Some files do not have the expected copyright lines") -end - -# UPDATE FILES ######################################################################### - -directories.each do |dir| - drectory_with_star = "#{dir}/*" - Dir[drectory_with_star].each do |item| - next if item == '.' or item == '..' or item == ".DS_Store" or File.directory?(item) - filename = "#{item}" - #puts filename - lines = [] - - File.open(filename, "r") do |input_file| - input_file.each_line do |line| - lines << line - end - end - - File.open(filename, "w") do |output_file| - - lines.each_with_index do |line, index| - - if index == 0 - output_file << new_identifier << "\n" - elsif index == 1 - output_file << new_copyright << "\n" - else - output_file << line - end - - end #lines.each - - end # File.open - - - - - end # foreach file - -end # foreach dir \ No newline at end of file diff --git a/gen/version-a/fromXElement.rb b/gen/version-a/fromXElement.rb deleted file mode 100755 index ea51cc8ae..000000000 --- a/gen/version-a/fromXElement.rb +++ /dev/null @@ -1,345 +0,0 @@ -require_relative "listEnums.rb" - -class_name = "" - -hlines = [] -clines = [] -hmembers = [] - -hline_private = -1 -cline_first_include = -1 -cline_last_function_close = -1 - -class Member - attr_accessor :member_type - attr_accessor :member_name - def to_s - "member_type: #{member_type}, member_name: #{member_name}" - end -end - -File.open("../../src/mx/core/elements/#{class_name}.h", "r") do |f| - - rx_private = / private\:/ - f.each_with_index do |line, index| - hlines << line - if ( line =~ rx_private ) != nil - hline_private = index - end - - #parse the members - if hline_private > 0 - rx_member = / ([a-zA-Z0-9]+) ([a-zA-Z0-9]+)/ - if ( line =~ rx_member ) != nil - matches = line.match(rx_member) - if !matches.nil? - member_type, member_name = matches.captures - m = Member.new - m.member_name = member_name - m.member_type = member_type - hmembers << m - end - end - end - end - - if hline_private < 0 - hline_private = hlines.length - 5 - end -end - -#test -#something = Member.new -#something.member_type = "bool" -#something.member_name = "myHasCreditChoice" -#hmembers << something - -def is_optional name, member_list - member_list.each do |m| - if m.member_name.eql? "myHas#{name[2..999]}" - - return true - end - end - return false -end - -def is_empty_with_attributes member_list - if member_list.length == 1 - if member_list[0].member_name.eql? "myAttributes" - return true - end - end - return false -end - -def is_set member_type - rx = /.+Set/ - return ( member_type =~ rx ) != nil -end - -def is_group member_type - rx = /.+GroupSet/ - if ( member_type =~ rx ) != nil - return true - end - - rx = /.+GroupPtr/ - if ( member_type =~ rx ) != nil - return true - end - return false -end - -def is_choice member_type - rx = /.+ChoiceSet/ - if ( member_type =~ rx ) != nil - return true - end - - rx = /.+ChoicePtr/ - if ( member_type =~ rx ) != nil - return true - end - return false -end - -def has_attributes member_list - member_list.each do |m| - if m.member_name.eql? "myAttributes" - return true - end - end - return false -end - -def is_bool member - return member.member_type.eql? "bool" -end - -def guts io, member_list, class_name - -io << " bool isSuccess = true;\n" - if has_attributes member_list -io << " isSuccess &= myAttributes->fromXElement( message, xelement );\n" - end - member_list.each do |m| - if is_bool m - next - elsif is_group m.member_type - next - elsif is_choice m.member_type - next - elsif is_set m.member_type - next - elsif m.member_name.eql? "myAttributes" - next - elsif !is_optional m.member_name, member_list -io << " bool is#{m.member_name[2..999]}Found = false;\n" - end - end -io << "\n" -io << " auto endIter = xelement.elementsEnd();\n" -io << " for( auto it = xelement.elementsBegin(); it != endIter; ++it )\n" -io << " {\n" - member_list.each do |m| - if is_bool m - next - elsif is_group m.member_type -io << " // groups #{m.member_name} \n\n" - elsif is_choice m.member_type -io << "\n /* if( checkSetChoiceMember(\n" -io << " message, *it, isSuccess, #{m.member_name},\n" -io << " \"elementname\", &#{m.member_name[2..999]}::getElementName,\n" -io << " static_cast( #{m.member_name[2..999]}::Choice::elementname ) ) )\n" -io << " { is#{m.member_name[2..999]}Found == true; continue; } */\n" - - elsif is_set m.member_type -io << " importElementSet( message, it, endIter, isSuccess, \"elementstring\", #{m.member_name} );\n" - elsif m.member_name.eql? "myAttributes" - next - elsif !is_optional m.member_name, member_list -io << " if ( importElement( message, *it, isSuccess, *#{m.member_name}, is#{m.member_name[2..999]}Found ) ) { continue; }\n" - else -io << " if ( importElement( message, *it, isSuccess, *#{m.member_name}, myHas#{m.member_name[2..999]} ) ) { continue; }\n" - end - end -io << " }\n" -io << "\n" - - - member_list.each do |m| - if is_bool m - next - elsif is_group m.member_type - next - elsif is_choice m.member_type - next - elsif is_set m.member_type - next - elsif m.member_name.eql? "myAttributes" - next - elsif !is_optional m.member_name, member_list -io << " if( !is#{m.member_name[2..999]}Found )\n" -io << " {\n" -io << " message << \"#{class_name}: '\" << #{m.member_name}->getElementName() << \"' is required but was not found\" << std::endl;\n" -io << " }\n" - end - end - - - -io << " return isSuccess;\n" -end - -def guts_empty_with_attributes io - io << " return myAttributes->fromXElement( message, xelement );\n" -end - -def is_value_with_attributes member_list - if member_list.length == 2 - if member_list[0].member_name.eql? "myAttributes" - if member_list[1].member_name.eql? "myValue" - return true - end - end - - if member_list[0].member_name.eql? "myValue" - if member_list[1].member_name.eql? "myAttributes" - return true - end - end - - end - return false -end - -def is_value_without_attributes member_list - - if member_list.length == 1 - - if member_list[0].member_name.eql? "myValue" - return true - end - - end - return false -end - - - -def is_empty_element member_list - if member_list.length == 0 - return true - end - return false -end - -def guts_empty_element io - io << " return true;\n" -end - -def setvalue_vs_parse member - rx = /Xs/ - if ( member.member_type =~ rx ) != nil - return "myValue.setValue" - elsif listEnums.include? member.member_type - return "myValue = parse#{member.member_type}" - end - return "myValue.parse" -end - -def guts_value_with_attributes io, members - io << " bool isSuccess = true;\n" - io << " isSuccess &= myAttributes->fromXElement( message, xelement );\n" - io << " #{setvalue_vs_parse(members[0])}( xelement.getValue() );\n" - io << " return isSuccess;\n" -end - -def guts_value_without_attributes io, members - io << " #{setvalue_vs_parse(members[0])}( xelement.getValue() );\n" - io << " return true;\n" -end - -File.open("../../src/mx/core/elements/#{class_name}.cpp", "r") do |f| - is_first_include_found = false - rx_first_include = /\#include/ - rx_function_close = / \}/ - - f.each_with_index do |line, index| - clines << line - - if !is_first_include_found - if ( line =~ rx_first_include ) != nil - cline_first_include = index - is_first_include_found = true - end - end - - if ( line =~ rx_function_close ) != nil - cline_last_function_close = index - end - end -end - - -File.open("../../src/mx/core/elements/#{class_name}.h", "w") do |f| - hlines.each_with_index do |line, index| - if( index == hline_private ) - f << " bool fromXElement( std::ostream& message, xml::XElement& xelement );" << "\n" - f << "\n" - end - f << line - end -end - - -File.open("../../src/mx/core/elements/#{class_name}.cpp", "w") do |f| - clines.each_with_index do |line, index| - if( index == cline_first_include ) - f << line - f << "\#include \"mx/core/FromXElement.h\"" << "\n" - next - end - - if( index == cline_last_function_close ) - f << line - f << "\n\n" -f << " bool #{class_name}::fromXElement( std::ostream& message, xml::XElement& xelement )\n" -f << " {\n" - - if is_empty_with_attributes hmembers - - guts_empty_with_attributes f - - - elsif is_value_with_attributes hmembers - - guts_value_with_attributes f, hmembers - - - elsif is_empty_element hmembers - - guts_empty_element f - - - elsif is_value_without_attributes hmembers - - guts_value_without_attributes f, hmembers - - - else - - guts f, hmembers, class_name - - end - -f << " }\n" - - - - next - end # end if( index == cline_last_function_close ) - f << line - end # end clines.each_with_index do |line, index| -end # end cfile write diff --git a/gen/version-a/fullNoteGroup.rb b/gen/version-a/fullNoteGroup.rb deleted file mode 100755 index 388e03750..000000000 --- a/gen/version-a/fullNoteGroup.rb +++ /dev/null @@ -1,130 +0,0 @@ - -require 'stringio' - -class String - def uncapitalize - self[0, 1].downcase + self[1..-1] - end -end - -class Member - attr_accessor :my_variable_name - attr_accessor :element_name - attr_accessor :is_set - attr_accessor :is_required - attr_accessor :element_name_for_cpp - - def initialize in_my_variable_name, in_element_name, in_description, in_element_name_for_cpp - @my_variable_name = in_my_variable_name - @element_name = in_element_name - @element_name_for_cpp = in_element_name_for_cpp - - if in_description.eql? "collection" - @is_set = true - @is_required = false - elsif in_description.eql? "required" - @is_set = false - @is_required = true - elsif in_description.eql? "optional" - @is_set = false - @is_required = false - else - @is_set = false - @is_required = false - end - end - - def is_found_variable - "is#{element_name_for_cpp}Found" - end - - def is_first_added_variable - "isFirst#{element_name_for_cpp}Added" - end - -end - -=begin -example_required_single = Member.new "myCreditWords", "credit-words", "required", "CreditWords" -example_optional_single = Member.new "myOptionalThing", "optional-thing", "optional", "OptionalThing" -example_collection = Member.new "myCatSet", "cat", "collection", "Cat" -=end - -group_class_name = "FullNoteGroup" - -members = [] - -#sample code -members << Member.new( "myChord", "chord", "optional", "Chord" ) -members << Member.new( "myFullNoteTypeChoice", "", "required", "FullNoteTypeChoice" ) - -code = StringIO.new -tab = " " -code << tab << tab << "bool #{group_class_name}::fromXElement( std::ostream& message, xml::XElement& xelement )" << "\n" -code << tab << tab << "{" << "\n" -code << tab << tab << tab << "bool isSuccess = true;" << "\n" - -members.each do |m| - if m.is_required && !m.is_set - code << tab << tab << tab << "bool #{m.is_found_variable} = false;" << "\n" - elsif m.is_set - code << tab << tab << tab << "bool #{m.is_first_added_variable} = false;" << "\n" - end -end -code << "\n" -code << tab << tab << tab << "for( auto it = xelement.elementsBegin(); it != xelement.elementsEnd(); ++it )" << "\n" -code << tab << tab << tab << "{" << "\n" -code << tab << tab << tab << tab << "const std::string elementName = it->getName();" << "\n" -code << "\n" -first_if = true -members.each do |m| - - code << tab << tab << tab << tab - if !first_if - code << "else " - end - first_if = false - code << "if( elementName == \"#{m.element_name}\" )" << "\n" - code << tab << tab << tab << tab << "{" << "\n" - if m.is_set -code << " auto #{m.element_name_for_cpp.uncapitalize} = make#{m.element_name_for_cpp}();" << "\n" -code << " isSuccess &= #{m.element_name_for_cpp.uncapitalize}->fromXElement( message, *it );" << "\n" -code << "\n" -code << " if( !#{m.is_first_added_variable} && #{m.my_variable_name}.size() == 1 )" << "\n" -code << " {" << "\n" -code << " *( #{m.my_variable_name}.begin() ) = #{m.element_name_for_cpp.uncapitalize};" << "\n" -code << " #{m.is_first_added_variable} = true;" << "\n" -code << " }" << "\n" -code << " else" << "\n" -code << " {" << "\n" -code << " #{m.my_variable_name}.push_back( #{m.element_name_for_cpp.uncapitalize} );" << "\n" -code << " #{m.is_first_added_variable} = true;" << "\n" -code << " }" << "\n" - elsif m.is_required -code << " #{m.is_found_variable} = true;" << "\n" -code << " isSuccess &= #{m.my_variable_name}->fromXElement( message, *it );" << "\n" - else -code << " myHas#{m.element_name_for_cpp} = true;" << "\n" -code << " isSuccess &= #{m.my_variable_name}->fromXElement( message, *it );" << "\n" - end - code << tab << tab << tab << tab << "}" << "\n" -end -code << tab << tab << tab << tab << "else" << "\n" -code << tab << tab << tab << tab << "{" << "\n" - -members.each do |m| - if m.is_required -code << " if( !#{m.is_found_variable} )" << "\n" -code << " {" << "\n" -code << " isSuccess = false;" << "\n" -code << " message << \"#{group_class_name}: '#{m.element_name}' element is required but was not found\" << std::endl;" << "\n" -code << " }" << "\n" - end -end -code << " break;" << "\n" -code << tab << tab << tab << tab << "}" << "\n" -code << tab << tab << tab << "}" << "\n" -code << tab << tab << tab << "return isSuccess;" << "\n" -code << tab << tab << "}" << "\n" - -puts code.string \ No newline at end of file diff --git a/gen/version-a/graceNoteGroup.rb b/gen/version-a/graceNoteGroup.rb deleted file mode 100755 index 144c8d0d9..000000000 --- a/gen/version-a/graceNoteGroup.rb +++ /dev/null @@ -1,131 +0,0 @@ - -require 'stringio' - -class String - def uncapitalize - self[0, 1].downcase + self[1..-1] - end -end - -class Member - attr_accessor :my_variable_name - attr_accessor :element_name - attr_accessor :is_set - attr_accessor :is_required - attr_accessor :element_name_for_cpp - - def initialize in_my_variable_name, in_element_name, in_description, in_element_name_for_cpp - @my_variable_name = in_my_variable_name - @element_name = in_element_name - @element_name_for_cpp = in_element_name_for_cpp - - if in_description.eql? "collection" - @is_set = true - @is_required = false - elsif in_description.eql? "required" - @is_set = false - @is_required = true - elsif in_description.eql? "optional" - @is_set = false - @is_required = false - else - @is_set = false - @is_required = false - end - end - - def is_found_variable - "is#{element_name_for_cpp}Found" - end - - def is_first_added_variable - "isFirst#{element_name_for_cpp}Added" - end - -end - -=begin -example_required_single = Member.new "myCreditWords", "credit-words", "required", "CreditWords" -example_optional_single = Member.new "myOptionalThing", "optional-thing", "optional", "OptionalThing" -example_collection = Member.new "myCatSet", "cat", "collection", "Cat" -=end - -group_class_name = "GraceNoteGroup" - -members = [] - -#sample code -members << Member.new( "myGrace", "grace", "required", "Grace" ) -members << Member.new( "myFullNoteGroup", "", "required", "FullNoteGroup" ) -members << Member.new( "myTieSet", "tie", "collection", "Tie" ) - -code = StringIO.new -tab = " " -code << tab << tab << "bool #{group_class_name}::fromXElement( std::ostream& message, xml::XElement& xelement )" << "\n" -code << tab << tab << "{" << "\n" -code << tab << tab << tab << "bool isSuccess = true;" << "\n" - -members.each do |m| - if m.is_required && !m.is_set - code << tab << tab << tab << "bool #{m.is_found_variable} = false;" << "\n" - elsif m.is_set - code << tab << tab << tab << "bool #{m.is_first_added_variable} = false;" << "\n" - end -end -code << "\n" -code << tab << tab << tab << "for( auto it = xelement.elementsBegin(); it != xelement.elementsEnd(); ++it )" << "\n" -code << tab << tab << tab << "{" << "\n" -code << tab << tab << tab << tab << "const std::string elementName = it->getName();" << "\n" -code << "\n" -first_if = true -members.each do |m| - - code << tab << tab << tab << tab - if !first_if - code << "else " - end - first_if = false - code << "if( elementName == \"#{m.element_name}\" )" << "\n" - code << tab << tab << tab << tab << "{" << "\n" - if m.is_set -code << " auto #{m.element_name_for_cpp.uncapitalize} = make#{m.element_name_for_cpp}();" << "\n" -code << " isSuccess &= #{m.element_name_for_cpp.uncapitalize}->fromXElement( message, *it );" << "\n" -code << "\n" -code << " if( !#{m.is_first_added_variable} && #{m.my_variable_name}.size() == 1 )" << "\n" -code << " {" << "\n" -code << " *( #{m.my_variable_name}.begin() ) = #{m.element_name_for_cpp.uncapitalize};" << "\n" -code << " #{m.is_first_added_variable} = true;" << "\n" -code << " }" << "\n" -code << " else" << "\n" -code << " {" << "\n" -code << " #{m.my_variable_name}.push_back( #{m.element_name_for_cpp.uncapitalize} );" << "\n" -code << " #{m.is_first_added_variable} = true;" << "\n" -code << " }" << "\n" - elsif m.is_required -code << " #{m.is_found_variable} = true;" << "\n" -code << " isSuccess &= #{m.my_variable_name}->fromXElement( message, *it );" << "\n" - else -code << " myHas#{m.element_name_for_cpp} = true;" << "\n" -code << " isSuccess &= #{m.my_variable_name}->fromXElement( message, *it );" << "\n" - end - code << tab << tab << tab << tab << "}" << "\n" -end -code << tab << tab << tab << tab << "else" << "\n" -code << tab << tab << tab << tab << "{" << "\n" - -members.each do |m| - if m.is_required -code << " if( !#{m.is_found_variable} )" << "\n" -code << " {" << "\n" -code << " isSuccess = false;" << "\n" -code << " message << \"#{group_class_name}: '#{m.element_name}' element is required but was not found\" << std::endl;" << "\n" -code << " }" << "\n" - end -end -code << " break;" << "\n" -code << tab << tab << tab << tab << "}" << "\n" -code << tab << tab << tab << "}" << "\n" -code << tab << tab << tab << "return isSuccess;" << "\n" -code << tab << tab << "}" << "\n" - -puts code.string \ No newline at end of file diff --git a/gen/version-a/groupCode.rb b/gen/version-a/groupCode.rb deleted file mode 100755 index 6d19fa828..000000000 --- a/gen/version-a/groupCode.rb +++ /dev/null @@ -1,130 +0,0 @@ - -require 'stringio' - -class String - def uncapitalize - self[0, 1].downcase + self[1..-1] - end -end - -class Member - attr_accessor :my_variable_name - attr_accessor :element_name - attr_accessor :is_set - attr_accessor :is_required - attr_accessor :element_name_for_cpp - - def initialize in_my_variable_name, in_element_name, in_description, in_element_name_for_cpp - @my_variable_name = in_my_variable_name - @element_name = in_element_name - @element_name_for_cpp = in_element_name_for_cpp - - if in_description.eql? "collection" - @is_set = true - @is_required = false - elsif in_description.eql? "required" - @is_set = false - @is_required = true - elsif in_description.eql? "optional" - @is_set = false - @is_required = false - else - @is_set = false - @is_required = false - end - end - - def is_found_variable - "is#{element_name_for_cpp}Found" - end - - def is_first_added_variable - "isFirst#{element_name_for_cpp}Added" - end - -end - -=begin -example_required_single = Member.new "myCreditWords", "credit-words", "required", "CreditWords" -example_optional_single = Member.new "myOptionalThing", "optional-thing", "optional", "OptionalThing" -example_collection = Member.new "myCatSet", "cat", "collection", "Cat" -=end - -group_class_name = "ArrowGroup" - -members = [] - -#sample code -members << Member.new( "myArrowDirection", "arrow-direction", "required", "ArrowDirection" ) -members << Member.new( "myArrowStyle", "arrow-style", "optional", "ArrowStyle" ) - -code = StringIO.new -tab = " " -code << tab << tab << "bool #{group_class_name}::fromXElement( std::ostream& message, xml::XElement& xelement )" << "\n" -code << tab << tab << "{" << "\n" -code << tab << tab << tab << "bool isSuccess = true;" << "\n" - -members.each do |m| - if m.is_required && !m.is_set - code << tab << tab << tab << "bool #{m.is_found_variable} = false;" << "\n" - elsif m.is_set - code << tab << tab << tab << "bool #{m.is_first_added_variable} = false;" << "\n" - end -end -code << "\n" -code << tab << tab << tab << "for( auto it = xelement.elementsBegin(); it != xelement.elementsEnd(); ++it )" << "\n" -code << tab << tab << tab << "{" << "\n" -code << tab << tab << tab << tab << "const std::string elementName = it->getName();" << "\n" -code << "\n" -first_if = true -members.each do |m| - - code << tab << tab << tab << tab - if !first_if - code << "else " - end - first_if = false - code << "if( elementName == \"#{m.element_name}\" )" << "\n" - code << tab << tab << tab << tab << "{" << "\n" - if m.is_set -code << " auto #{m.element_name_for_cpp.uncapitalize} = make#{m.element_name_for_cpp.uncapitalize}();" << "\n" -code << " isSuccess &= #{m.element_name_for_cpp.uncapitalize}->fromXElement( message, *it );" << "\n" -code << "\n" -code << " if( !#{m.is_first_added_variable} && #{m.my_variable_name}.size() == 1 )" << "\n" -code << " {" << "\n" -code << " *( #{m.my_variable_name}.begin() ) = #{m.element_name_for_cpp.uncapitalize};" << "\n" -code << " #{m.is_first_added_variable} = true;" << "\n" -code << " }" << "\n" -code << " else" << "\n" -code << " {" << "\n" -code << " #{m.my_variable_name}.push_back( #{m.element_name_for_cpp.uncapitalize} );" << "\n" -code << " #{m.is_first_added_variable} = true;" << "\n" -code << " }" << "\n" - elsif m.is_required -code << " #{m.is_found_variable} = true;" << "\n" -code << " isSuccess &= #{m.my_variable_name}->fromXElement( message, *it );" << "\n" - else -code << " myHas#{m.element_name_for_cpp} = true;" << "\n" -code << " isSuccess &= #{m.my_variable_name}->fromXElement( message, *it );" << "\n" - end - code << tab << tab << tab << tab << "}" << "\n" -end -code << tab << tab << tab << tab << "else" << "\n" -code << tab << tab << tab << tab << "{" << "\n" - -members.each do |m| - if m.is_required -code << " if( !#{m.is_found_variable} )" << "\n" -code << " {" << "\n" -code << " isSuccess = false;" << "\n" -code << " message << \"#{group_class_name}: '#{m.element_name}' element is required but was not found\" << std::endl;" << "\n" -code << " }" << "\n" - end -end -code << " break;" << "\n" -code << tab << tab << tab << tab << "}" << "\n" -code << tab << tab << tab << "}" << "\n" -code << tab << tab << tab << "return isSuccess;" << "\n" -code << tab << tab << "}" << "\n" - -puts code.string \ No newline at end of file diff --git a/gen/version-a/includeAlot.rb b/gen/version-a/includeAlot.rb deleted file mode 100755 index 95ae53250..000000000 --- a/gen/version-a/includeAlot.rb +++ /dev/null @@ -1,9 +0,0 @@ -require 'pathname' - -filepaths = Dir["../../src/mx/core/elements/*"] - -filepaths.each do |fp| - filename = Pathname.new(fp).basename - classname = File.basename( fp, ".*" ) - puts "#include \"mx/core/elements/#{classname}.h\"" -end diff --git a/gen/version-a/includeAttributesIfNeeded.rb b/gen/version-a/includeAttributesIfNeeded.rb deleted file mode 100755 index 908d07251..000000000 --- a/gen/version-a/includeAttributesIfNeeded.rb +++ /dev/null @@ -1,12 +0,0 @@ - -require_relative "isSymbolFound.rb" - -def includeAttributesIfNeeded( symbol_list, code_snippet_to_search, include_file_path ) - return_value = "" - symbol_list.each do |symbol| - if isSymbolFound(code_snippet_to_search,symbol) - return "#include \"#{include_file_path}\"\n" - end - end - return_value -end \ No newline at end of file diff --git a/gen/version-a/includeEnumsIfNeeded.rb b/gen/version-a/includeEnumsIfNeeded.rb deleted file mode 100755 index 39b6130e1..000000000 --- a/gen/version-a/includeEnumsIfNeeded.rb +++ /dev/null @@ -1,17 +0,0 @@ - -require_relative "isSymbolFound.rb" - -def includeEnumsIfNeeded( enum_symbols, enum_class_symbols, code_snippet_to_search ) - return_value = "" - enum_symbols.each do |enum_symbol| - if isSymbolFound(code_snippet_to_search,enum_symbol) - return "#include \"mx/core/Enums.h\"\n" - end - end - enum_class_symbols.each do |enum_class_symbol| - if isSymbolFound(code_snippet_to_search,enum_class_symbol) - return "#include \"mx/core/Enums.h\"\n" - end - end - return_value -end \ No newline at end of file diff --git a/gen/version-a/includeIfNeeded.rb b/gen/version-a/includeIfNeeded.rb deleted file mode 100755 index 58ffa68f8..000000000 --- a/gen/version-a/includeIfNeeded.rb +++ /dev/null @@ -1,20 +0,0 @@ - -require_relative "isSymbolFound.rb" - -def includeIfNeeded( symbol_list, code_snippet_to_search, include_file_path ) - return_value = "" - symbol_list.each do |symbol| - if isSymbolFound(code_snippet_to_search,symbol) - return "#include \"#{include_file_path}\"\n" - end - end - return_value -end - -def includeOneIfNeeded( symbol, code_snippet_to_search, include_file_path ) - return_value = "" - if isSymbolFound(code_snippet_to_search,symbol) - return "#include \"#{include_file_path}\"\n" - end - return_value -end \ No newline at end of file diff --git a/gen/version-a/includeStandaloneIfNeeded.rb b/gen/version-a/includeStandaloneIfNeeded.rb deleted file mode 100755 index f518e29fe..000000000 --- a/gen/version-a/includeStandaloneIfNeeded.rb +++ /dev/null @@ -1,16 +0,0 @@ -require "set" -require_relative "isSymbolFound.rb" - -def includeStandaloneIfNeeded( symbol, code_snippet_to_search ) - return_value = "" - if isSymbolFound(code_snippet_to_search,symbol) - return "#include \"mx/core/#{symbol}.h\"\n" - end - if isSymbolFound(code_snippet_to_search,"#{symbol}Ptr") - return "#include \"mx/core/#{symbol}.h\"\n" - end - if isSymbolFound(code_snippet_to_search,"#{symbol}Set") - return "#include \"mx/core/#{symbol}.h\"\n" - end - return_value -end \ No newline at end of file diff --git a/gen/version-a/isSymbolFound.rb b/gen/version-a/isSymbolFound.rb deleted file mode 100755 index 4fa4f88d0..000000000 --- a/gen/version-a/isSymbolFound.rb +++ /dev/null @@ -1,5 +0,0 @@ - -def isSymbolFound ( code_string_to_search_in, symbol_name_to_find ) - rx = /(\s#{symbol_name_to_find}\s|\s#{symbol_name_to_find}\&)/ - ( code_string_to_search_in =~ rx ) != nil -end \ No newline at end of file diff --git a/gen/version-a/layoutGroup.rb b/gen/version-a/layoutGroup.rb deleted file mode 100755 index 81b1d221a..000000000 --- a/gen/version-a/layoutGroup.rb +++ /dev/null @@ -1,130 +0,0 @@ - -require 'stringio' - -class String - def uncapitalize - self[0, 1].downcase + self[1..-1] - end -end - -class Member - attr_accessor :my_variable_name - attr_accessor :element_name - attr_accessor :is_set - attr_accessor :is_required - attr_accessor :element_name_for_cpp - - def initialize in_my_variable_name, in_element_name, in_description, in_element_name_for_cpp - @my_variable_name = in_my_variable_name - @element_name = in_element_name - @element_name_for_cpp = in_element_name_for_cpp - - if in_description.eql? "collection" - @is_set = true - @is_required = false - elsif in_description.eql? "required" - @is_set = false - @is_required = true - elsif in_description.eql? "optional" - @is_set = false - @is_required = false - else - @is_set = false - @is_required = false - end - end - - def is_found_variable - "is#{element_name_for_cpp}Found" - end - - def is_first_added_variable - "isFirst#{element_name_for_cpp}Added" - end - -end - -=begin -example_required_single = Member.new "myCreditWords", "credit-words", "required", "CreditWords" -example_optional_single = Member.new "myOptionalThing", "optional-thing", "optional", "OptionalThing" -example_collection = Member.new "myCatSet", "cat", "collection", "Cat" -=end - -group_class_name = "MetronomeRelationGroup" - -members = [] - -#sample code -members << Member.new( "myMetronomeRelation", "metronome-relation", "required", "MetronomeRelation" ) -members << Member.new( "myMetronomeNote", "metronome-note", "required", "MetronomeNote" ) - -code = StringIO.new -tab = " " -code << tab << tab << "bool #{group_class_name}::fromXElement( std::ostream& message, xml::XElement& xelement )" << "\n" -code << tab << tab << "{" << "\n" -code << tab << tab << tab << "bool isSuccess = true;" << "\n" - -members.each do |m| - if m.is_required && !m.is_set - code << tab << tab << tab << "bool #{m.is_found_variable} = false;" << "\n" - elsif m.is_set - code << tab << tab << tab << "bool #{m.is_first_added_variable} = false;" << "\n" - end -end -code << "\n" -code << tab << tab << tab << "for( auto it = xelement.elementsBegin(); it != xelement.elementsEnd(); ++it )" << "\n" -code << tab << tab << tab << "{" << "\n" -code << tab << tab << tab << tab << "const std::string elementName = it->getName();" << "\n" -code << "\n" -first_if = true -members.each do |m| - - code << tab << tab << tab << tab - if !first_if - code << "else " - end - first_if = false - code << "if( elementName == \"#{m.element_name}\" )" << "\n" - code << tab << tab << tab << tab << "{" << "\n" - if m.is_set -code << " auto #{m.element_name_for_cpp.uncapitalize} = make#{m.element_name_for_cpp}();" << "\n" -code << " isSuccess &= #{m.element_name_for_cpp.uncapitalize}->fromXElement( message, *it );" << "\n" -code << "\n" -code << " if( !#{m.is_first_added_variable} && #{m.my_variable_name}.size() == 1 )" << "\n" -code << " {" << "\n" -code << " *( #{m.my_variable_name}.begin() ) = #{m.element_name_for_cpp.uncapitalize};" << "\n" -code << " #{m.is_first_added_variable} = true;" << "\n" -code << " }" << "\n" -code << " else" << "\n" -code << " {" << "\n" -code << " #{m.my_variable_name}.push_back( #{m.element_name_for_cpp.uncapitalize} );" << "\n" -code << " #{m.is_first_added_variable} = true;" << "\n" -code << " }" << "\n" - elsif m.is_required -code << " #{m.is_found_variable} = true;" << "\n" -code << " isSuccess &= #{m.my_variable_name}->fromXElement( message, *it );" << "\n" - else -code << " myHas#{m.element_name_for_cpp} = true;" << "\n" -code << " isSuccess &= #{m.my_variable_name}->fromXElement( message, *it );" << "\n" - end - code << tab << tab << tab << tab << "}" << "\n" -end -code << tab << tab << tab << tab << "else" << "\n" -code << tab << tab << tab << tab << "{" << "\n" - -members.each do |m| - if m.is_required -code << " if( !#{m.is_found_variable} )" << "\n" -code << " {" << "\n" -code << " isSuccess = false;" << "\n" -code << " message << \"#{group_class_name}: '#{m.element_name}' element is required but was not found\" << std::endl;" << "\n" -code << " }" << "\n" - end -end -code << " break;" << "\n" -code << tab << tab << tab << tab << "}" << "\n" -code << tab << tab << tab << "}" << "\n" -code << tab << tab << tab << "return isSuccess;" << "\n" -code << tab << tab << "}" << "\n" - -puts code.string \ No newline at end of file diff --git a/gen/version-a/lineInstructionsH.rb b/gen/version-a/lineInstructionsH.rb deleted file mode 100755 index 34d97024b..000000000 --- a/gen/version-a/lineInstructionsH.rb +++ /dev/null @@ -1,132 +0,0 @@ -require 'stringio' - -require_relative "parseElementsH.rb" - -class LineInfo - attr_accessor :name - attr_accessor :inherits_from - attr_accessor :forward_declaration_line - attr_accessor :make_default_line - attr_accessor :declaration_line - attr_accessor :end_line - - def initialize - @name = "" - @inherits_from = "" - @forward_declaration_line = -1 - @make_default_line = -1 - @declaration_line = -1 - @end_line = -1 - end - - def to_s - ss = StringIO.new - ss << "#{name}," - ss << "#{inherits_from}," - ss << "#{forward_declaration_line}," - ss << "#{make_default_line}," - ss << "#{declaration_line}," - ss << "#{end_line}" - ss.string - end -end - -def findDefaultMakeLine line_info, code_lines - if line_info.inherits_from.eql? "AttributesInterface" - return - end - rx = /make#{line_info.name}\(\)/ - #rx = /.*/ - start = line_info.forward_declaration_line - stop = line_info.declaration_line - #puts "start: #{start}" - #puts "stop: #{stop}" - for i in start..stop - line = code_lines[i] - #puts "i: #{i}" - #puts "code_lines[i]: #{code_lines[i]}" - #puts "line: #{line}" - if ( line =~ rx ) != nil - #puts "BINGO!!!!!!!!!!!!!!!!!!!!!!!!!!" - line_info.make_default_line = i - end - end -end - -def findDefaultMakeLinesForAll line_info_collection, code_lines - line_info_collection.each do |li| - findDefaultMakeLine li, code_lines - end -end - -def lineInstructionsH - - lines = [] - - File.open("../../src/mx/core/Elements.h", "r") do |f| - f.each_line do |line| - lines << line - end - end - - parsed_h = parseElementsH - - - - temp_line_instructions = [] - - line_info = LineInfo.new - start_flag = false - - parsed_h.each do |i| - if i.description.eql? "forward_declaration" - #puts i.description - line_info.name = i.name - line_info.forward_declaration_line = i.line_number - next - end - - if i.description.eql? "declaration" - #puts i.description - line_info.inherits_from = i.inherits_from - line_info.declaration_line = i.line_number - next - end - - #if start_flag - # if i.inherits_from != "" - # line_info.inherits_from = i.inherits_from - # end - #end - - if i.description.eql? "close_brace" - # puts "hello" - start_flag = false - line_info.end_line = i.line_number - temp_line_instructions << line_info - line_info = LineInfo.new - end - end - - final_line_instructions = [] - - previous_li = temp_line_instructions[0] - - temp_line_instructions.each_with_index do |li,index| - if ( li.name.nil? || li.name.eql?( "" ) ) - previous_li.end_line = li.end_line - else - final_line_instructions << previous_li - previous_li = LineInfo.new - previous_li = li - end - end - - final_line_instructions << previous_li - - findDefaultMakeLinesForAll final_line_instructions, lines - #puts final_line_instructions - final_line_instructions -end - -#puts lineInstructionsH \ No newline at end of file diff --git a/gen/version-a/listAttributeClasses.rb b/gen/version-a/listAttributeClasses.rb deleted file mode 100755 index 4b886fc82..000000000 --- a/gen/version-a/listAttributeClasses.rb +++ /dev/null @@ -1,32 +0,0 @@ -require "set" -require_relative "parseElementsH.rb" - -class AttributeClass - -end - - -def listAttributeClasses - - elements_result = parseElementsH - - attribute_classes = SortedSet.new - - elements_result.each do |ed| - if ed.description.eql? "declaration" - if ed.inherits_from.eql? "AttributesInterface" - attribute_classes << ed.name - end - end - end - - #attribute_classes << "InvertedMordentAttributes" - #attribute_classes << "ToeAttributes" - - attribute_classes -end - - -#listAttributeClasses.each do |ac| -# puts ac -#end diff --git a/gen/version-a/listClassesInEnumsH.rb b/gen/version-a/listClassesInEnumsH.rb deleted file mode 100755 index f78e9c584..000000000 --- a/gen/version-a/listClassesInEnumsH.rb +++ /dev/null @@ -1,22 +0,0 @@ -require "set" - -def listClassesInEnumsH - - enum_list = SortedSet.new - - File.open("../../src/mx/core/Enums.h", "r") do |f| - f.each_line do |line| - rx = /^\s+class\s([a-zA-Z0-9]+)/ - matches = line.match(rx) - if !matches.nil? - caps = matches.captures - enum_name = caps[0] - enum_list << enum_name - #puts enum_name - end - end - end - - enum_list - -end diff --git a/gen/version-a/listDecimals.rb b/gen/version-a/listDecimals.rb deleted file mode 100755 index b19f6407b..000000000 --- a/gen/version-a/listDecimals.rb +++ /dev/null @@ -1,39 +0,0 @@ -require "set" - -def listDecimals - - item_list = SortedSet.new - - File.open("../../src/mx/core/Decimals.h", "r") do |f| - f.each_line do |line| - rx = /^\s+class\s([a-zA-Z0-9]+)/ - matches = line.match(rx) - if !matches.nil? - caps = matches.captures - enum_name = caps[0] - item_list << enum_name - #puts enum_name - end - - rx = /^\s+using\s([a-zA-Z0-9]+)/ - matches = line.match(rx) - if !matches.nil? - caps = matches.captures - enum_name = caps[0] - item_list << enum_name - #puts enum_name - end - - end - end - - item_list.delete("impl") - item_list << "kDefaultPrecision" - item_list << "kNonZeroAmount" - return item_list -end - - -#listDecimals.each do |d| -# puts d -#end \ No newline at end of file diff --git a/gen/version-a/listElementClasses.rb b/gen/version-a/listElementClasses.rb deleted file mode 100755 index e0e04636a..000000000 --- a/gen/version-a/listElementClasses.rb +++ /dev/null @@ -1,31 +0,0 @@ -require "set" -require_relative "parseElementsH.rb" - -class ElementClass - -end - - -def listElementClasses - - elements_result = parseElementsH - - element_classes = SortedSet.new - - elements_result.each do |ed| - if ed.description.eql? "declaration" - if ed.inherits_from.eql? "ElementInterface" - element_classes << ed.name - end - end - end - - element_classes << "EditorialVoiceDirectionGroup" - - element_classes -end - - -#listElementClasses.each do |ec| -# puts ec -#end diff --git a/gen/version-a/listEnums.rb b/gen/version-a/listEnums.rb deleted file mode 100755 index 7bcebf0b4..000000000 --- a/gen/version-a/listEnums.rb +++ /dev/null @@ -1,27 +0,0 @@ -require "set" - -def listEnums - - enum_list = SortedSet.new - - File.open("../../src/mx/core/Enums.h", "r") do |f| - f.each_line do |line| - rx = /^\s+enum\sclass\s([a-zA-Z0-9]+)/ - matches = line.match(rx) - if !matches.nil? - caps = matches.captures - enum_name = caps[0] - enum_list << enum_name - #puts enum_name - end - end - end - - enum_list - -end - - -#listEnums.each do |e| -# puts e -#end \ No newline at end of file diff --git a/gen/version-a/listIntegers.rb b/gen/version-a/listIntegers.rb deleted file mode 100755 index 90e44a5fd..000000000 --- a/gen/version-a/listIntegers.rb +++ /dev/null @@ -1,39 +0,0 @@ -require "set" - -def listIntegers - - item_list = SortedSet.new - - File.open("../../src/mx/core/Integers.h", "r") do |f| - f.each_line do |line| - rx = /^\s+class\s([a-zA-Z0-9]+)/ - matches = line.match(rx) - if !matches.nil? - caps = matches.captures - enum_name = caps[0] - item_list << enum_name - #puts enum_name - end - - rx = /^\s+using\s([a-zA-Z0-9]+)/ - matches = line.match(rx) - if !matches.nil? - caps = matches.captures - enum_name = caps[0] - item_list << enum_name - #puts enum_name - end - - end - end - - #item_list.delete("impl") - #item_list << "kDefaultPrecision" - #item_list << "kNonZeroAmount" - item_list -end - - -#listIntegers.each do |d| -# puts d -#end \ No newline at end of file diff --git a/gen/version-a/listSpecialClasses.rb b/gen/version-a/listSpecialClasses.rb deleted file mode 100755 index a8dce5236..000000000 --- a/gen/version-a/listSpecialClasses.rb +++ /dev/null @@ -1,20 +0,0 @@ - -require 'set' - - - -def listSpecialClasses - - list = SortedSet.new - - list << "Color" - list << "Date" - list << "FontSize" - list << "NumberOrNormal" - list << "PositiveIntegerOrEmpty" - list << "YesNoNumber" - - return list -end - -#puts listSpecialClasses \ No newline at end of file diff --git a/gen/version-a/listStrings.rb b/gen/version-a/listStrings.rb deleted file mode 100755 index fa2334f3e..000000000 --- a/gen/version-a/listStrings.rb +++ /dev/null @@ -1,39 +0,0 @@ -require "set" - -def listStrings - - item_list = SortedSet.new - - File.open("../../src/mx/core/Strings.h", "r") do |f| - f.each_line do |line| - rx = /^\s+class\s([a-zA-Z0-9]+)/ - matches = line.match(rx) - if !matches.nil? - caps = matches.captures - enum_name = caps[0] - item_list << enum_name - #puts enum_name - end - - rx = /^\s+using\s([a-zA-Z0-9]+)/ - matches = line.match(rx) - if !matches.nil? - caps = matches.captures - enum_name = caps[0] - item_list << enum_name - #puts enum_name - end - - end - end - - #item_list.delete("impl") - #item_list << "kDefaultPrecision" - #item_list << "kNonZeroAmount" - item_list -end - - -#listStrings.each do |d| -# puts d -#end \ No newline at end of file diff --git a/gen/version-a/midiDeviceInstrumentGroup.rb b/gen/version-a/midiDeviceInstrumentGroup.rb deleted file mode 100755 index 2745773ce..000000000 --- a/gen/version-a/midiDeviceInstrumentGroup.rb +++ /dev/null @@ -1,130 +0,0 @@ - -require 'stringio' - -class String - def uncapitalize - self[0, 1].downcase + self[1..-1] - end -end - -class Member - attr_accessor :my_variable_name - attr_accessor :element_name - attr_accessor :is_set - attr_accessor :is_required - attr_accessor :element_name_for_cpp - - def initialize in_my_variable_name, in_element_name, in_description, in_element_name_for_cpp - @my_variable_name = in_my_variable_name - @element_name = in_element_name - @element_name_for_cpp = in_element_name_for_cpp - - if in_description.eql? "collection" - @is_set = true - @is_required = false - elsif in_description.eql? "required" - @is_set = false - @is_required = true - elsif in_description.eql? "optional" - @is_set = false - @is_required = false - else - @is_set = false - @is_required = false - end - end - - def is_found_variable - "is#{element_name_for_cpp}Found" - end - - def is_first_added_variable - "isFirst#{element_name_for_cpp}Added" - end - -end - -=begin -example_required_single = Member.new "myCreditWords", "credit-words", "required", "CreditWords" -example_optional_single = Member.new "myOptionalThing", "optional-thing", "optional", "OptionalThing" -example_collection = Member.new "myCatSet", "cat", "collection", "Cat" -=end - -group_class_name = "NormalTypeNormalDotGroup" - -members = [] - -#sample code -members << Member.new( "myNormalType", "normal-type", "required", "NormalType" ) -members << Member.new( "myNormalDotSet", "normal-dot", "collection", "NormalDot" ) - -code = StringIO.new -tab = " " -code << tab << tab << "bool #{group_class_name}::fromXElement( std::ostream& message, xml::XElement& xelement )" << "\n" -code << tab << tab << "{" << "\n" -code << tab << tab << tab << "bool isSuccess = true;" << "\n" - -members.each do |m| - if m.is_required && !m.is_set - code << tab << tab << tab << "bool #{m.is_found_variable} = false;" << "\n" - elsif m.is_set - code << tab << tab << tab << "bool #{m.is_first_added_variable} = false;" << "\n" - end -end -code << "\n" -code << tab << tab << tab << "for( auto it = xelement.elementsBegin(); it != xelement.elementsEnd(); ++it )" << "\n" -code << tab << tab << tab << "{" << "\n" -code << tab << tab << tab << tab << "const std::string elementName = it->getName();" << "\n" -code << "\n" -first_if = true -members.each do |m| - - code << tab << tab << tab << tab - if !first_if - code << "else " - end - first_if = false - code << "if( elementName == \"#{m.element_name}\" )" << "\n" - code << tab << tab << tab << tab << "{" << "\n" - if m.is_set -code << " auto #{m.element_name_for_cpp.uncapitalize} = make#{m.element_name_for_cpp}();" << "\n" -code << " isSuccess &= #{m.element_name_for_cpp.uncapitalize}->fromXElement( message, *it );" << "\n" -code << "\n" -code << " if( !#{m.is_first_added_variable} && #{m.my_variable_name}.size() == 1 )" << "\n" -code << " {" << "\n" -code << " *( #{m.my_variable_name}.begin() ) = #{m.element_name_for_cpp.uncapitalize};" << "\n" -code << " #{m.is_first_added_variable} = true;" << "\n" -code << " }" << "\n" -code << " else" << "\n" -code << " {" << "\n" -code << " #{m.my_variable_name}.push_back( #{m.element_name_for_cpp.uncapitalize} );" << "\n" -code << " #{m.is_first_added_variable} = true;" << "\n" -code << " }" << "\n" - elsif m.is_required -code << " #{m.is_found_variable} = true;" << "\n" -code << " isSuccess &= #{m.my_variable_name}->fromXElement( message, *it );" << "\n" - else -code << " myHas#{m.element_name_for_cpp} = true;" << "\n" -code << " isSuccess &= #{m.my_variable_name}->fromXElement( message, *it );" << "\n" - end - code << tab << tab << tab << tab << "}" << "\n" -end -code << tab << tab << tab << tab << "else" << "\n" -code << tab << tab << tab << tab << "{" << "\n" - -members.each do |m| - if m.is_required -code << " if( !#{m.is_found_variable} )" << "\n" -code << " {" << "\n" -code << " isSuccess = false;" << "\n" -code << " message << \"#{group_class_name}: '#{m.element_name}' element is required but was not found\" << std::endl;" << "\n" -code << " }" << "\n" - end -end -code << " break;" << "\n" -code << tab << tab << tab << tab << "}" << "\n" -code << tab << tab << tab << "}" << "\n" -code << tab << tab << tab << "return isSuccess;" << "\n" -code << tab << tab << "}" << "\n" - -puts code.string \ No newline at end of file diff --git a/gen/version-a/mxdeploy b/gen/version-a/mxdeploy deleted file mode 100755 index 894977b00..000000000 --- a/gen/version-a/mxdeploy +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/bash -rm -rf /Users/mjb/MxBin/Build/Products/ - -# build iOS -xcodebuild \ - -workspace ~/Dropbox/Programming/MxRepo/xcode/mx.xcworkspace \ - -scheme dylib-iOS \ - build \ - -derivedDataPath ~/MxBin \ - -destination generic/platform=iOS \ - -destination 'generic/platform=iOS simulator' - -# combine the two outputs into one "fat" binary -mv /Users/mjb/MxBin/Build/Products/Debug-iphoneos/libmx-iOS.dylib /Users/mjb/MxBin/Build/Products/Debug-iphoneos/libmx-iOS.dylib.deviceonly -mv /Users/mjb/MxBin/Build/Products/Debug-iphonesimulator/libmx-iOS.dylib /Users/mjb/MxBin/Build/Products/Debug-iphonesimulator/libmx-iOS.dylib.iphonesimulator - -lipo -create -output "/Users/mjb/MxBin/Build/Products/Debug-iphoneos/libmx-iOS.dylib" /Users/mjb/MxBin/Build/Products/Debug-iphoneos/libmx-iOS.dylib.deviceonly /Users/mjb/MxBin/Build/Products/Debug-iphonesimulator/libmx-iOS.dylib.iphonesimulator - -# cleanup the no-longer-needed stuff -rm /Users/mjb/MxBin/Build/Products/Debug-iphoneos/libmx-iOS.dylib.deviceonly -rm /Users/mjb/MxBin/Build/Products/Debug-iphonesimulator/libmx-iOS.dylib.iphonesimulator -rm -rf /Users/mjb/MxBin/Build/Products/Debug-iphonesimulator - -# build macOS -xcodebuild \ - -workspace ~/Dropbox/Programming/MxRepo/xcode/mx.xcworkspace \ - -scheme dylib-macOS \ - build \ - -derivedDataPath ~/MxBin \ - -destination 'platform=OS X,arch=x86_64' - -# move to komp repo -rm -f /Users/mjb/komp/Frameworks/mx/bin/libmx-iOS.dylib -rm -f /Users/mjb/komp/Frameworks/mx/bin/libmx-macOS.dylib -cp /Users/mjb/MxBin/Build/Products/Debug-iphoneos/libmx-iOS.dylib /Users/mjb/komp/Frameworks/mx/bin/libmx-iOS.dylib -cp /Users/mjb/MxBin/Build/Products/Debug/libmx-macOS.dylib /Users/mjb/komp/Frameworks/mx/bin/libmx-macOS.dylib -rm -rf /Users/mjb/komp/Frameworks/mx/headers/ -mkdir /Users/mjb/komp/Frameworks/mx/headers -mkdir /Users/mjb/komp/Frameworks/mx/headers/mx -mkdir /Users/mjb/komp/Frameworks/mx/headers/mx/api -cp /Users/mjb/Dropbox/Programming/MxRepo/src/mx/api/*.h /Users/mjb/komp/Frameworks/mx/headers/mx/api diff --git a/gen/version-a/mxdeploy-v01.rb b/gen/version-a/mxdeploy-v01.rb deleted file mode 100644 index cfd4bed67..000000000 --- a/gen/version-a/mxdeploy-v01.rb +++ /dev/null @@ -1,128 +0,0 @@ - -require 'fileutils' - -configuration = "Release" -config = configuration.downcase - -build_root = "/Users/mjb/mxout" -mx_repo_root = "/Users/mjb/Dropbox/Programming/MxRepo" -komp_repo_root = "Users/mjb/komp" -lib_ios = "libMx-iOS.a" -lib_macOS = "libMx-macOS.a" -mx_version_defines_h = "#{mx_repo_root}/src/mx/impl/MxVersionDefines.h" -upload_dir = "/Users/mjb/Dropbox/Programming/MxKompDeploy" - -version_major = 0 -version_minor = 0 -version_patch = 0 -version_build = 0 - -f = File.open("#{mx_version_defines_h}", "r") -f.each_line do |line| - if (line[0..24] <=> "#define MX_VERSION_MAJOR ") == 0 - version_major = Integer( line[25..-1] ) - end -end - -f.close -f = File.open("#{mx_version_defines_h}", "r") -f.each_line do |line| - if (line[0..24] <=> "#define MX_VERSION_MINOR ") == 0 - version_minor = Integer( line[25..-1] ) - end -end - -f.close -f = File.open("#{mx_version_defines_h}", "r") -f.each_line do |line| - if (line[0..24] <=> "#define MX_VERSION_PATCH ") == 0 - version_patch = Integer( line[25..-1] ) - end -end -f.close - -f = File.open("#{mx_version_defines_h}", "r") -f.each_line do |line| - if (line[0..24] <=> "#define MX_VERSION_BUILD ") == 0 - version_build = Integer( line[25..-1] ) - end -end -f.close - -version_build = Integer( version_build ) + 1 - -FileUtils.rm("#{mx_version_defines_h}") - -open("#{mx_version_defines_h}", 'w') { |f| - f << "#define MX_VERSION_MAJOR #{version_major}\n" - f << "#define MX_VERSION_MINOR #{version_minor}\n" - f << "#define MX_VERSION_PATCH #{version_patch}\n" - f << "#define MX_VERSION_BUILD #{version_build}\n" -} - -version = "#{version_major}.#{version_minor}.#{version_patch}.#{version_build}" -puts "building version #{version}" - -build_ios = "xcodebuild \ - -workspace #{mx_repo_root}/xcode/mx.xcworkspace \ - -scheme Mx-iOS \ - build \ - -derivedDataPath #{build_root} \ - -destination generic/platform=iOS \ - -destination 'generic/platform=iOS simulator' \ - -configuration #{configuration}" - -is_success = system( build_ios ) - -if !is_success - raise 'ios build failed' -end - -build_mac = "xcodebuild \ - -workspace #{mx_repo_root}/xcode/mx.xcworkspace \ - -scheme Mx-macOS \ - build \ - -derivedDataPath #{build_root} \ - -destination generic/platform=macOS \ - -destination 'platform=OS X,arch=x86_64' \ - -configuration #{configuration}" - -is_success = system( build_mac ) - -if !is_success - raise 'macos build failed' -end - -universal_output_dir = "#{build_root}/Build/Universal/#{configuration}" -FileUtils.rm_rf(universal_output_dir) -FileUtils::mkdir_p universal_output_dir - -lipo_output_a = "#{universal_output_dir}/#{lib_ios}" -ios_input_a = "#{build_root}/Build/Products/#{configuration}-iphoneos/#{lib_ios}" -i386_input_a = "#{build_root}/Build/Products/#{configuration}-iphonesimulator/#{lib_ios}" -x86_64_a = "#{build_root}/Build/Products/#{configuration}/#{lib_macOS}" - -lipo_cmd = "lipo -create -output \"#{lipo_output_a}\" \"#{ios_input_a}\" \"#{i386_input_a}\"" -is_success = system( lipo_cmd ) - -if !is_success - raise 'lipo failed' -end - -final_name = "mx-deploy-#{config}-#{version}" -final_output_dir = "#{build_root}/#{final_name}" -FileUtils.rm_rf(final_output_dir) -FileUtils::mkdir_p final_output_dir - -FileUtils.cp(lipo_output_a, "#{final_output_dir}") -FileUtils.cp(x86_64_a, "#{final_output_dir}") - -header_output_dir = "#{final_output_dir}/include/mx/api" -FileUtils::mkdir_p header_output_dir -FileUtils.copy_entry "#{mx_repo_root}/src/mx/api", "#{header_output_dir}" - -system( "cd \"#{build_root}\" && tar -zcvf \"#{final_name}.tar.gz\" \"#{final_name}\"" ) - -FileUtils.cp("#{build_root}/#{final_name}.tar.gz", "#{upload_dir}") -FileUtils.rm_rf(final_output_dir) -FileUtils.rm_rf("#{build_root}/#{final_name}.tar.gz") diff --git a/gen/version-a/mxdeploy-v02.rb b/gen/version-a/mxdeploy-v02.rb deleted file mode 100644 index ee700c217..000000000 --- a/gen/version-a/mxdeploy-v02.rb +++ /dev/null @@ -1,106 +0,0 @@ - -require 'fileutils' - -########################################################################### -# -# Define directory paths -# -########################################################################### - -name_mx_pkg = "mx-src-pkg" -name_mx_src = "src" -name_mx_proj = "xcode" - -dir_this_ruby_script = File.dirname(File.realpath(__FILE__)) -dir_mx_root = "#{dir_this_ruby_script}/../.." -dir_mx_src = "#{dir_mx_root}/#{name_mx_src}" -dir_mx_proj = "#{dir_mx_root}/#{name_mx_proj}" -dir_komp_root = "/Users/mjb/komp" -dir_komp_mx_root = "#{dir_komp_root}/Frameworks/mx" -dir_komp_mx_deploy = "#{dir_komp_mx_root}/src-pkg" -dir_temp_root = "/Users/mjb/mx-temp" - -file_mx_version_defines_h = "#{dir_mx_src}/mx/impl/MxVersionDefines.h" - -########################################################################### -# -# Find the current version, increment the build number by one, and save -# it. Use the resulting version to define the name of the package that we -# are deploying and store it to name_mx_pkg suffixing the value that was -# given above with the version number. -# -########################################################################### - -version_major = 0 -version_minor = 0 -version_patch = 0 -version_build = 0 - -f = File.open("#{file_mx_version_defines_h}", "r") -f.each_line do |line| - if (line[0..24] <=> "#define MX_VERSION_MAJOR ") == 0 - version_major = Integer( line[25..-1] ) - end - if (line[0..24] <=> "#define MX_VERSION_MINOR ") == 0 - version_minor = Integer( line[25..-1] ) - end - if (line[0..24] <=> "#define MX_VERSION_PATCH ") == 0 - version_patch = Integer( line[25..-1] ) - end - if (line[0..24] <=> "#define MX_VERSION_BUILD ") == 0 - version_build = Integer( line[25..-1] ) - end -end - -version_build = Integer( version_build ) + 1 -FileUtils.rm("#{file_mx_version_defines_h}") -open("#{file_mx_version_defines_h}", 'w') { |f| - f << "#define MX_VERSION_MAJOR #{version_major}\n" - f << "#define MX_VERSION_MINOR #{version_minor}\n" - f << "#define MX_VERSION_PATCH #{version_patch}\n" - f << "#define MX_VERSION_BUILD #{version_build}\n" -} - -version = "#{version_major}.#{version_minor}.#{version_patch}.#{version_build}" -name_mx_pkg = "#{name_mx_pkg}-#{version}" -puts "deploying #{name_mx_pkg}" - -########################################################################### -# -# Copy sourcecode and xcode projects to a temporary directory, then zip the -# the temporary directory and delete the unzipped version. -# -########################################################################### - -dir_temp = "#{dir_temp_root}/#{name_mx_pkg}" -name_mx_pkg_zipped = "#{name_mx_pkg}.tar.gz" -file_zipped = "#{dir_temp_root}/#{name_mx_pkg_zipped}" -FileUtils.rm_rf(dir_temp) -FileUtils::mkdir_p dir_temp -FileUtils.cp_r "#{dir_mx_src}", "#{dir_temp}/#{name_mx_src}", :verbose => true -FileUtils.cp_r "#{dir_mx_proj}", "#{dir_temp}/#{name_mx_proj}", :verbose => true -system( "cd \"#{dir_temp_root}\" && tar -zcvf \"#{name_mx_pkg_zipped}\" \"#{name_mx_pkg}\"" ) -FileUtils.rm_rf("#{dir_temp}") - -########################################################################### -# -# Copy zipped sourcecode to the komp repo and create a file there which -# indicates the version which is in use -# -########################################################################### -FileUtils.cp "#{file_zipped}", "#{dir_komp_mx_deploy}" -file_current = "#{dir_komp_mx_deploy}/current.txt" -File.delete(file_current) if File.exist?(file_current) -open(file_current, 'w') { |f| - f << "#{name_mx_pkg_zipped}" -} - -########################################################################### -# -# Make a commit in the mx repo to record this version -# -########################################################################### -Dir.chdir dir_mx_root -system ( "git add --all" ) -system ( "git commit -m\"deployed #{name_mx_pkg}\"" ) - diff --git a/gen/version-a/mxdeploy.rb b/gen/version-a/mxdeploy.rb deleted file mode 100644 index 91ef3c9d9..000000000 --- a/gen/version-a/mxdeploy.rb +++ /dev/null @@ -1,239 +0,0 @@ -require 'fileutils' -require 'tmpdir' - -########################################################################### -# -# Define directory and file paths -# -########################################################################### - -configuration = "Release" - -name_mx_pkg = "mx-version" -name_mx_src = "src" -name_mx_proj = "xcode" -name_versioning_file = "current.txt" -name_ios_target = "MxiOS" -name_osx_target = "MxmacOS" -name_ios = "lib#{name_ios_target}" -name_osx = "lib#{name_osx_target}" -name_ios_framework = "#{name_ios_target}.framework" -name_osx_framework = "#{name_osx_target}.framework" - -dir_build = "/Users/mjb/mx-temp" -dir_this_ruby_script = File.dirname(File.realpath(__FILE__)) -dir_mx_root = File.expand_path("#{dir_this_ruby_script}/../..") -file_mx_xcode_workspace = "#{dir_mx_root}/xcode/mx.xcworkspace" -file_mx_version_defines_h = "#{dir_mx_root}/src/mx/impl/MxVersionDefines.h" - -dir_komp_root = "/Users/mjb/repos/komp" -dir_komp_mx = "#{dir_komp_root}/Frameworks/mx" -dir_komp_mx_bin = "#{dir_komp_mx}/bin" -dir_komp_mx_src = "#{dir_komp_mx}/src" -dir_komp_mx_headers = "#{dir_komp_mx}/headers" - - -########################################################################### -# -# Find the current version, increment the build number by one, and save -# it. Use the resulting version to define the name of the package that we -# are deploying and store it to name_mx_pkg suffixing the value that was -# given above with the version number. -# -########################################################################### - -version_major = 0 -version_minor = 0 -version_patch = 0 -version_build = 0 - -f = File.open("#{file_mx_version_defines_h}", "r") -f.each_line do |line| - if (line[0..24] <=> "#define MX_VERSION_MAJOR ") == 0 - version_major = Integer( line[25..-1] ) - end - if (line[0..24] <=> "#define MX_VERSION_MINOR ") == 0 - version_minor = Integer( line[25..-1] ) - end - if (line[0..24] <=> "#define MX_VERSION_PATCH ") == 0 - version_patch = Integer( line[25..-1] ) - end - if (line[0..24] <=> "#define MX_VERSION_BUILD ") == 0 - version_build = Integer( line[25..-1] ) - end -end - -version_build = Integer( version_build ) + 1 -FileUtils.rm("#{file_mx_version_defines_h}") -open("#{file_mx_version_defines_h}", 'w') { |f| - f << "#define MX_VERSION_MAJOR #{version_major}\n" - f << "#define MX_VERSION_MINOR #{version_minor}\n" - f << "#define MX_VERSION_PATCH #{version_patch}\n" - f << "#define MX_VERSION_BUILD #{version_build}\n" -} - -version = "#{version_major}.#{version_minor}.#{version_patch}.#{version_build}" -name_mx_pkg = "#{name_mx_pkg}-#{version}" -puts "deploying #{name_mx_pkg}" - -########################################################################### -# -# Build Mx -# -########################################################################### - -build_ios = "xcodebuild \ - -workspace #{file_mx_xcode_workspace} \ - -scheme #{name_ios_target} \ - build \ - -derivedDataPath #{dir_build} \ - -destination 'generic/platform=iOS' \ - -destination 'generic/platform=iOS simulator' \ - -configuration #{configuration}" - -is_success = system( build_ios ) - -if !is_success - raise 'ios build failed' -end - -build_mac = "xcodebuild \ - -workspace #{file_mx_xcode_workspace} \ - -scheme #{name_osx_target} \ - build \ - -derivedDataPath #{dir_build} \ - -destination generic/platform=macOS \ - -destination 'platform=OS X,arch=x86_64' \ - -configuration #{configuration}" - -is_success = system( build_mac ) - -if !is_success - raise 'macos build failed' -end - -########################################################################### -# -# Create a directory for the output -# -########################################################################### - -dir_out = "#{dir_build}/../mx-out" -FileUtils.rm_rf(dir_out) -FileUtils::mkdir_p dir_out - -########################################################################### -# -# Move and Lipo the frameworks -# -########################################################################### - -dir_ios_framework_fat = "#{dir_out}/#{name_ios_framework}" -dir_ios_iphone_only = "#{dir_build}/Build/Products/#{configuration}-iphoneos/#{name_ios_framework}" -dir_ios_i386___only = "#{dir_build}/Build/Products/#{configuration}-iphonesimulator/#{name_ios_framework}" -FileUtils.rm_rf(dir_ios_framework_fat) -FileUtils.mkdir_p(dir_ios_framework_fat) -FileUtils::copy_entry(dir_ios_iphone_only, dir_ios_framework_fat) - -file_lipo_output = "#{dir_out}/#{name_ios_framework}/#{name_ios_target}" -file_lipo_input_a = "#{dir_ios_iphone_only}/#{name_ios_target}" -file_lipo_input_b = "#{dir_ios_i386___only}/#{name_ios_target}" - -FileUtils.rm(file_lipo_output) - -cmd_lipo = "lipo -create -output \"#{file_lipo_output}\" \"#{file_lipo_input_a}\" \"#{file_lipo_input_b}\"" -is_success = system( cmd_lipo ) - -if !is_success - raise "lipo failed" -end - -dir_osx_framework = "#{dir_out}/#{name_osx_framework}" -dir_osx_build_result = "#{dir_build}/Build/Products/#{configuration}/#{name_osx_framework}" -FileUtils.rm_rf(dir_osx_framework) -FileUtils.mkdir_p(dir_osx_framework) -FileUtils::copy_entry(dir_osx_build_result, dir_osx_framework) - -########################################################################### -# -# Deploy to Komp -# -########################################################################### - -dir_komp_mx_ios_framework = "#{dir_komp_mx_bin}/#{name_ios_framework}" -FileUtils.rm_rf(dir_komp_mx_ios_framework) -FileUtils.mkdir_p(dir_komp_mx_ios_framework) -FileUtils::copy_entry(dir_ios_framework_fat, dir_komp_mx_ios_framework) - -dir_komp_mx_osx_framework = "#{dir_komp_mx_bin}/#{name_osx_framework}" -FileUtils.rm_rf(dir_komp_mx_osx_framework) -FileUtils.mkdir_p(dir_komp_mx_osx_framework) -FileUtils::copy_entry(dir_osx_build_result, dir_komp_mx_osx_framework) - -########################################################################### -# -# Copy Headers -# -########################################################################### - -FileUtils.rm_rf(dir_komp_mx_headers) -FileUtils::mkdir_p "#{dir_komp_mx_headers}/mx/api" - -file_header_list = Dir["#{dir_mx_root}/src/mx/api/*.h"] - -file_header_list.each do |file_current_header| - FileUtils.cp(file_current_header, "#{dir_komp_mx_headers}/mx/api") -end - -########################################################################### -# -# Write version info -# -########################################################################### - -name_version = "current-mx-version.txt" -file_version_bin = "#{dir_komp_mx_bin}/#{name_version}" -file_version_src = "#{dir_komp_mx_src}/#{name_version}" -file_version_hed = "#{dir_komp_mx_headers}/#{name_version}" - -File.delete(file_version_bin) if File.exist?(file_version_bin) -open(file_version_bin, 'w') { |f| - f << "#{name_mx_pkg}" -} - -File.delete(file_version_src) if File.exist?(file_version_src) -open(file_version_src, 'w') { |f| - f << "#{name_mx_pkg}" -} - -File.delete(file_version_hed) if File.exist?(file_version_hed) -open(file_version_hed, 'w') { |f| - f << "#{name_mx_pkg}" -} - -########################################################################### -# -# zip and save a copy of mx sourcecode to the komp repo for backup -# -########################################################################### - -dir_code_copy_before_zipping = "#{dir_build}/#{name_mx_pkg}" -name_zipped_filename = "#{name_mx_pkg}.tar.gz" -file_zipped_source = "#{dir_build}/#{name_zipped_filename}" -FileUtils.mkdir_p "#{dir_code_copy_before_zipping}/src" -FileUtils.cp_r "#{dir_mx_root}/src", "#{dir_code_copy_before_zipping}/src" -FileUtils.mkdir_p "#{dir_code_copy_before_zipping}/xcode" -FileUtils.cp_r "#{dir_mx_root}/xcode", "#{dir_code_copy_before_zipping}/xcode" -system( "cd \"#{dir_build}\" && tar -zcvf \"#{name_zipped_filename}\" \"#{name_mx_pkg}\"" ) -FileUtils.cp "#{file_zipped_source}", "#{dir_komp_mx_src}" -FileUtils.rm_rf(dir_code_copy_before_zipping) - -########################################################################### -# -# make a commit in the git repo that corresponds to this deployment -# -########################################################################### - -Dir.chdir dir_mx_root -system ( "git add --all" ) -system ( "git commit -m\"#{name_mx_pkg}\"" ) \ No newline at end of file diff --git a/gen/version-a/note.rb b/gen/version-a/note.rb deleted file mode 100755 index 4a8a8b893..000000000 --- a/gen/version-a/note.rb +++ /dev/null @@ -1,143 +0,0 @@ - -require 'stringio' - -class String - def uncapitalize - self[0, 1].downcase + self[1..-1] - end -end - -class Member - attr_accessor :my_variable_name - attr_accessor :element_name - attr_accessor :is_set - attr_accessor :is_required - attr_accessor :element_name_for_cpp - - def initialize in_my_variable_name, in_element_name, in_description, in_element_name_for_cpp - @my_variable_name = in_my_variable_name - @element_name = in_element_name - @element_name_for_cpp = in_element_name_for_cpp - - if in_description.eql? "collection" - @is_set = true - @is_required = false - elsif in_description.eql? "required" - @is_set = false - @is_required = true - elsif in_description.eql? "optional" - @is_set = false - @is_required = false - else - @is_set = false - @is_required = false - end - end - - def is_found_variable - "is#{element_name_for_cpp}Found" - end - - def is_first_added_variable - "isFirst#{element_name_for_cpp}Added" - end - -end - -=begin -example_required_single = Member.new "myCreditWords", "credit-words", "required", "CreditWords" -example_optional_single = Member.new "myOptionalThing", "optional-thing", "optional", "OptionalThing" -example_collection = Member.new "myCatSet", "cat", "collection", "Cat" -=end - -group_class_name = "Note" - -members = [] - -#sample code -members << Member.new( "myNoteChoice", "NOTAPPLICABLE", "required", "NoteChoice" ) -members << Member.new( "myInstrument", "instrument", "optional", "Instrument" ) -members << Member.new( "myEditorialVoiceGroup", "NOTAPPLICABLE", "required", "EditorialVoiceGroup" ) -members << Member.new( "myType", "type", "optional", "Type" ) -members << Member.new( "myDotSet", "dot", "collection", "Dot" ) -members << Member.new( "myAccidental", "accidental", "optional", "Accidental" ) -members << Member.new( "myTimeModification", "time-modification", "optional", "TimeModification" ) -members << Member.new( "myStem", "stem", "optional", "Stem" ) -members << Member.new( "myNotehead", "notehead", "optional", "Notehead" ) -members << Member.new( "myNoteheadText", "notehead-text", "optional", "NoteheadText" ) -members << Member.new( "myStaff", "staff", "optional", "Staff" ) -members << Member.new( "myBeamSet", "beam", "collection", "Beam" ) -members << Member.new( "myNotationsSet", "notations", "collection", "Notations" ) -members << Member.new( "myLyricSet", "lyric", "collection", "Lyric" ) -members << Member.new( "myPlay", "play", "optional", "Play" ) - -code = StringIO.new -tab = " " -code << tab << tab << "bool #{group_class_name}::fromXElement( std::ostream& message, xml::XElement& xelement )" << "\n" -code << tab << tab << "{" << "\n" -code << tab << tab << tab << "bool isSuccess = true;" << "\n" - -members.each do |m| - if m.is_required && !m.is_set - code << tab << tab << tab << "bool #{m.is_found_variable} = false;" << "\n" - elsif m.is_set - code << tab << tab << tab << "bool #{m.is_first_added_variable} = false;" << "\n" - end -end -code << "\n" -code << tab << tab << tab << "for( auto it = xelement.elementsBegin(); it != xelement.elementsEnd(); ++it )" << "\n" -code << tab << tab << tab << "{" << "\n" -code << tab << tab << tab << tab << "const std::string elementName = it->getName();" << "\n" -code << "\n" -first_if = true -members.each do |m| - - code << tab << tab << tab << tab - if !first_if - code << "else " - end - first_if = false - code << "if( elementName == \"#{m.element_name}\" )" << "\n" - code << tab << tab << tab << tab << "{" << "\n" - if m.is_set -code << " auto #{m.element_name_for_cpp.uncapitalize} = make#{m.element_name_for_cpp}();" << "\n" -code << " isSuccess &= #{m.element_name_for_cpp.uncapitalize}->fromXElement( message, *it );" << "\n" -code << "\n" -code << " if( !#{m.is_first_added_variable} && #{m.my_variable_name}.size() == 1 )" << "\n" -code << " {" << "\n" -code << " *( #{m.my_variable_name}.begin() ) = #{m.element_name_for_cpp.uncapitalize};" << "\n" -code << " #{m.is_first_added_variable} = true;" << "\n" -code << " }" << "\n" -code << " else" << "\n" -code << " {" << "\n" -code << " #{m.my_variable_name}.push_back( #{m.element_name_for_cpp.uncapitalize} );" << "\n" -code << " #{m.is_first_added_variable} = true;" << "\n" -code << " }" << "\n" - elsif m.is_required -code << " #{m.is_found_variable} = true;" << "\n" -code << " isSuccess &= #{m.my_variable_name}->fromXElement( message, *it );" << "\n" - else -code << " myHas#{m.element_name_for_cpp} = true;" << "\n" -code << " isSuccess &= #{m.my_variable_name}->fromXElement( message, *it );" << "\n" - end - code << tab << tab << tab << tab << "}" << "\n" -end -code << tab << tab << tab << tab << "else" << "\n" -code << tab << tab << tab << tab << "{" << "\n" - -members.each do |m| - if m.is_required -code << " if( !#{m.is_found_variable} )" << "\n" -code << " {" << "\n" -code << " isSuccess = false;" << "\n" -code << " message << \"#{group_class_name}: '#{m.element_name}' element is required but was not found\" << std::endl;" << "\n" -code << " }" << "\n" - end -end -code << " break;" << "\n" -code << tab << tab << tab << tab << "}" << "\n" -code << tab << tab << tab << "}" << "\n" -code << tab << tab << tab << "return isSuccess;" << "\n" -code << tab << tab << "}" << "\n" - -puts code.string \ No newline at end of file diff --git a/gen/version-a/parseElementsCpp.rb b/gen/version-a/parseElementsCpp.rb deleted file mode 100755 index ce6af74eb..000000000 --- a/gen/version-a/parseElementsCpp.rb +++ /dev/null @@ -1,103 +0,0 @@ - -require "stringio" -require "set" -require_relative "listElementClasses.rb" -require_relative "listAttributeClasses.rb" - -class CppFunction - attr_accessor :class_name - attr_accessor :func_name - attr_accessor :first_line - attr_accessor :last_line - def to_s - ss = StringIO.new - ss << "#{class_name}," - ss << "#{func_name}," - ss << "#{first_line}," - ss << "#{last_line}" - ss.string - end -end - -def parseElementsCpp - element_classes = listElementClasses - attribute_classes = listAttributeClasses - all_classes = SortedSet.new - all_classes.merge element_classes - all_classes.merge attribute_classes - - - cpp_functions = [] - - File.open("../../src/mx/core/Elements.cpp", "r") do |f| - f.each_with_index do |line, index| - - rx_scope_operator = /([a-zA-Z0-9]+)\:\:([a-zA-Z0-9]+)/ - rx_scope_operator_matches = line.match(rx_scope_operator) - if rx_scope_operator_matches.nil? - next - end - - if line.include? "//" - next - end - - class_name, func_name = rx_scope_operator_matches.captures - - if class_name.nil? || class_name.empty? - next - end - - if func_name.nil? || func_name.empty? - next - end - - if class_name.eql? "std" - next - end - - if class_name.eql? "core" - next - end - - if all_classes.member? class_name - func = CppFunction.new - func.first_line = index - func.class_name = class_name - func.func_name = func_name - func.last_line = -1 - cpp_functions << func - end - end - - previous_cpp_function = CppFunction.new - current_cpp_function = CppFunction.new - - cpp_functions.each do |f| - current_cpp_function = f - if !previous_cpp_function.first_line.nil? - previous_cpp_function.last_line = ( current_cpp_function.first_line - 1 ) - end - previous_cpp_function = current_cpp_function - end - - previous_cpp_function.last_line = 37340 - - cpp_functions - end -end - -=begin - -cpp_functions = parseElementsCpp -classes = listElementClasses - - -classes.each do |c| - puts "-------------------" - local_functions = cpp_functions.select { |func| func.class_name.eql? c } - local_functions.each do |f| - puts f - end -end -=end diff --git a/gen/version-a/parseElementsH.rb b/gen/version-a/parseElementsH.rb deleted file mode 100755 index e14a60324..000000000 --- a/gen/version-a/parseElementsH.rb +++ /dev/null @@ -1,129 +0,0 @@ -require 'stringio' -require 'set' - -class HDeclarationLine - attr_accessor :line_number - attr_accessor :name - attr_accessor :object_type - attr_accessor :inherits_from - attr_accessor :description - def to_s - ss = StringIO.new - ss << "#{line_number}," - ss << "#{name}," - ss << "#{object_type}," - ss << "#{inherits_from}," - ss << "#{description}" - ss.string - end -end - -def parseElementsH - declarations_found = [] - - File.open("../../src/mx/core/Elements.h", "r") do |f| - f.each_with_index do |line, index| - rx = /^\s*class\s[^\s\;]+/ - is_class = ( line =~ rx ) != nil - - rx = /^\s*struct\s[^\s\;]+/ - is_struct = ( line =~ rx ) != nil - - object_type = "struct" - if is_class - object_type = "class" - end - - is_forward_dec = false - - rx = /^\s.*class.*\;.*$/ - if ( line =~ rx ) != nil - is_forward_dec = true - end - - rx = /^\s.*struct.*\;.*$/ - if ( line =~ rx ) != nil - is_forward_dec = true - end - - rx = /^\s*class\s([^\s\;]+)/ - name = "" - matches = line.match(rx) - if !matches.nil? - caps = matches.captures - name = caps[0] - #puts name - end - - rx = /^\s*struct\s([^\s\;]+)/ - matches = line.match(rx) - if !matches.nil? - caps = matches.captures - name = caps[0] - #puts name - end - - rx = /\:\s+public\s+([a-zA-Z]+)/ - inherits = "" - is_decl = false - if is_class || is_struct - if !is_forward_dec - matches = line.match(rx) - if !matches.nil? - caps = matches.captures - inherits = caps[0] - is_decl = true - end - end - end - - if is_class || is_struct - addthis = HDeclarationLine.new - addthis.line_number = index - addthis.name = name - addthis.object_type = object_type - addthis.inherits_from = inherits - if is_forward_dec - addthis.description = "forward_declaration" - elsif is_decl - addthis.description = "declaration" - end - - declarations_found << addthis - end - - if !is_class && !is_struct - rx = /^\s+\{/ - if ( line =~ rx ) != nil - addthis = HDeclarationLine.new - addthis.line_number = index - addthis.name = "" - addthis.object_type = "" - addthis.inherits_from = "" - addthis.description = "open_brace" - declarations_found << addthis - end - end - - if !is_class && !is_struct - rx = /^\s+\}\;/ - if ( line =~ rx ) != nil - addthis = HDeclarationLine.new - addthis.line_number = index - addthis.name = "" - addthis.object_type = "" - addthis.inherits_from = "" - addthis.description = "close_brace" - declarations_found << addthis - end - end - - end - end - - declarations_found -end - - -#stuff = parseElementsH -#puts stuff diff --git a/gen/version-a/parseElementsHOrder.rb b/gen/version-a/parseElementsHOrder.rb deleted file mode 100755 index e45cb81b7..000000000 --- a/gen/version-a/parseElementsHOrder.rb +++ /dev/null @@ -1,37 +0,0 @@ -lines = [] - -File.open("../../src/mx/core/Elements.h", "r") do |input_file| - input_file.each_line do |line| - lines << line - end -end - -i = 1 -#File.open("../../src/mx/core/Elements.h.order.csv", "w") do |f| - write_line = true - lines.each do |line| - - rx = /\s{8}class\s([a-zA-Z0-9\_]+)\s\:/ - matches = line.match(rx) - - if !matches.nil? - caps = matches.captures - name = caps[0] - f << "#{i},#{name},ElementInterface\n" - i = (i + 1) - next - end - - rx = /\s{8}struct\s([a-zA-Z0-9\_]+)\s\:/ - matches = line.match(rx) - - if !matches.nil? - caps = matches.captures - name = caps[0] - f << "#{i},#{name},AttributesInterface\n" - i = (i + 1) - next - end - - end -end \ No newline at end of file diff --git a/gen/version-a/parseXsd.rb b/gen/version-a/parseXsd.rb deleted file mode 100644 index 913d34f09..000000000 --- a/gen/version-a/parseXsd.rb +++ /dev/null @@ -1,9 +0,0 @@ -require 'rexml/document' -require 'rexml/xpath' -doc = REXML::Document.new(File.new('../../docs/musicxml.xsd')) - -stuff = doc.elements.to_a - -REXML::XPath.each(doc, "//xs:element") { |element| - puts element.attributes["name"] -} \ No newline at end of file diff --git a/gen/version-a/smuflHeader.rb b/gen/version-a/smuflHeader.rb deleted file mode 100644 index 7f6c716bd..000000000 --- a/gen/version-a/smuflHeader.rb +++ /dev/null @@ -1,52 +0,0 @@ -require 'json' -require 'stringio' - -j = JSON.parse( IO.read("../../data/smufl/glyphnames.json")) - -content = StringIO.new - -content << "// MusicXML Class Library v0.3.0\n" -content << "// Copyright (c) 2015 - 2016 by Matthew James Briggs\n" -content << "\n" -content << "#pragma once\n" -content << "\n" -content << "#include \n" -content << "#include \n" -content << "\n" -content << "namespace mx\n" -content << "{\n" -content << " namespace impl\n" -content << " {\n" -content << " inline std::map createS-M-U-F-LMap()\n" -content << " {\n" -content << " std::map outMap;\n" - -#content << " outMap.emplace(std::make_pair( "4stringTabClef", 0xE06E ));\n" - - -j.each_with_index do |item,index| - content << " " - content << "outMap.emplace(std::make_pair( \"#{item[0]}\", " - content << "0x" - content << item[1]["codepoint"][2..-1] - content << " )); // glyphnumber: #{index}, #{item[1]["description"]}" - content << "\n" - #puts index - #puts item[0] - #puts item[1]["codepoint"] - #puts item[1]["description"] -end - -content << " return outMap;\n" -content << " }\n" -content << " }\n" -content << "}\n" - -begin - file = File.open("../../src/mx/impl/S-M-U-F-LGlyphMap.h", "w") - file.write(content.string) -rescue IOError => e - #some error occur, dir not writable etc. -ensure - file.close unless file.nil? -end diff --git a/gen/version-a/todo.txt b/gen/version-a/todo.txt deleted file mode 100755 index 12e45cfe6..000000000 --- a/gen/version-a/todo.txt +++ /dev/null @@ -1,23 +0,0 @@ - - -After the above is working put the ruby scripts into a "trash" folder (clever -name perhaps) and start over with new ruby scripts that read from the new h -and cpp files. Begin implementing the fromXDoc functions one-at-a-time. - - ----- comments -/* I am renaming this to "properties" because it clashes with a lot of things. - In particular it clashes with the Attributes which are contained by every - element. I discovered this clash late in the game so this is likely to be - the only Element where the element's name does not match the Class name. */ - - - - - void MetronomeRelation::setValue( const XsString& value ) - { - // No! This is weird, the only allowed value is "equals" - // per the specification, so the client cannot change - // the value - // myValue = value; - } \ No newline at end of file diff --git a/gen/version-a/version.rb b/gen/version-a/version.rb deleted file mode 100755 index dc4259371..000000000 --- a/gen/version-a/version.rb +++ /dev/null @@ -1,17 +0,0 @@ -lines = [] - -File.open("../../src/mx/core/AttributesInterface.h", "r") do |input_file| - input_file.each_line do |line| - lines << line - end -end - -rx = /\/\/\sMusicXML\sClass\sLibrary\sv0\.1\.1/ -is_first_line_correct = ( ( lines[0] =~ rx ) != nil ) - -rx = /\/\/\sCopyright\s\(c\)\s2015\s\-\s2016\sby\sMatthew\sJames\sBriggs/ -is_second_line_correct = ( ( lines[1] =~ rx ) != nil ) - -if ( !is_first_line_correct ) || ( !is_second_line_correct ) - puts "filename" -end \ No newline at end of file diff --git a/gen/version-a/writeElementsCppFiles.rb b/gen/version-a/writeElementsCppFiles.rb deleted file mode 100755 index fcf199ae1..000000000 --- a/gen/version-a/writeElementsCppFiles.rb +++ /dev/null @@ -1,125 +0,0 @@ -require 'stringio' -require 'set' - -require_relative "parseElementsCpp.rb" -require_relative "listElementClasses.rb" -require_relative "listAttributeClasses.rb" -require_relative "lineInstructionsH.rb" -require_relative "includeIfNeeded.rb" - -def doIncludes io_object, line_info_object - if line_info_object == nil - puts "ERROR line_info_object is nil" - return - end - element_classes = listElementClasses - lines = [] - - File.open("../../src/mx/core/Elements.h", "r") do |f| - f.each_line do |line| - lines << line - end - end - - code_stringio = StringIO.new - for i in line_info_object.forward_declaration_line..line_info_object.end_line - code_stringio << "#{lines[i]}" - end - code = code_stringio.string - - - element_classes.each do |e| - if !e.eql? line_info_object.name - io_object << includeOneIfNeeded( "#{e}Ptr", code, "mx/core/elements/#{e}.h" ) - end - end - - io_object << "#include \n" -end - -def openNamespaces io_object - io_object << "namespace mx\n" - io_object << "{\n" - io_object << " namespace core\n" - io_object << " {\n" -end - -def closeNamespaces io_object - io_object << " }\n" - io_object << "}\n" -end - -def emptyLine io_object - io_object << "\n" -end - -def includeH io_object, class_name - io_object << "#include \"mx/core/elements/#{class_name}.h\"\n" -end - -def copywrite io_object - io_object << "// MusicXML Class Library v0.1.1\n" - io_object << "// Copyright (c) 2015 - 2016 by Matthew James Briggs\n" -end - -def writeCppFile class_name, original_file_lines, function_objects - - line_info_objects = lineInstructionsH - line_info_selected = line_info_objects.select { |li| li.name.eql? class_name } - - if line_info_selected.size == 0 - puts "ERROR line_info_object not found for #{class_name}" - end - - line_info = line_info_selected[0] - - File.open("../../src/mx/core/elements/#{class_name}.cpp", "w") do |f| - copywrite f - emptyLine f - includeH( f, class_name ) - doIncludes( f, line_info ) - emptyLine f - openNamespaces f - - # functions - function_objects.each do |func| - original_file_lines[func.first_line..func.last_line].each do |line| - f << line - end - emptyLine f - emptyLine f - end - - - closeNamespaces f - end -end - - -lines = [] - -File.open("../../src/mx/core/Elements.cpp", "r") do |f| - f.each_line do |line| - lines << line - end -end - -classes = listElementClasses -attributes = listAttributeClasses -all_symbols = SortedSet.new -all_symbols.merge classes -all_symbols.merge attributes - -all_functions = parseElementsCpp - -all_symbols.each do |c| - local_functions = all_functions.select { |func| func.class_name.eql? c } - writeCppFile c, lines, local_functions -end - - - - -#puts all_functions.count - -#writeCppFile "temp", lines, functions \ No newline at end of file diff --git a/gen/version-a/writeHFiles.rb b/gen/version-a/writeHFiles.rb deleted file mode 100755 index f88435b62..000000000 --- a/gen/version-a/writeHFiles.rb +++ /dev/null @@ -1,199 +0,0 @@ -require 'stringio' - -require_relative "lineInstructionsH.rb" -require_relative "listEnums.rb" -require_relative "listClassesInEnumsH.rb" -require_relative "listStrings.rb" -require_relative "listDecimals.rb" -require_relative "listIntegers.rb" -require_relative "includeEnumsIfNeeded.rb" -require_relative "includeIfNeeded.rb" -require_relative "includeStandaloneIfNeeded.rb" -require_relative "listAttributeClasses.rb" -require_relative "listElementClasses.rb" -require_relative "elementsHUsingFile.rb" - - -#def forwardDeclare class_name -# " MX_FORWARD_DECLARE( #{class_name} )\n" -#end - -def forwardDeclareAttributesIfNeeded( io_object, symbol_name, code ) - if (!isSymbolFound( code , "#{symbol_name}Ptr" ))&&(!isSymbolFound( code , "#{symbol_name}Set" ))&&(!isSymbolFound( code , symbol_name )) - return - end - - #old way - #io_object << " struct #{symbol_name};\n" - #io_object << " using #{symbol_name}Ptr = std::shared_ptr<#{symbol_name}>;\n" - - #new way - io_object << " MX_FORWARD_DECLARE_ATTRIBUTES( #{symbol_name} )\n" - - #io_object << "\n" -end - -def forwardDeclareElementIfNeeded( io_object, symbol_name, code ) - if (!isSymbolFound( code , "#{symbol_name}Ptr" ))&&(!isSymbolFound( code , "#{symbol_name}Set" ))&&(!isSymbolFound( code , symbol_name )) - return - end - - #old way - #io_object << " class #{symbol_name};\n" - #io_object << " using #{symbol_name}Ptr = std::shared_ptr<#{symbol_name}>;\n" - #io_object << " using #{symbol_name}Set = std::vector<#{symbol_name}Ptr>;\n" - #io_object << " using #{symbol_name}SetIter = #{symbol_name}Set::iterator;\n" - #io_object << " using #{symbol_name}SetIterConst = #{symbol_name}Set::const_iterator;\n" - - #new way - io_object << " MX_FORWARD_DECLARE_ELEMENT( #{symbol_name} )\n" - #io_object << "\n" -end - -def getCodeAsString line_instruction, h_file_code_lines - code_stringio = StringIO.new - stop = line_instruction.end_line - start = line_instruction.declaration_line - - first_make = line_instruction.make_default_line - - if ( first_make > 0 ) - if ( first_make ) < start - start = ( first_make ) - end - end - - for i in start..stop - code_stringio << "#{h_file_code_lines[i]}" - end - - code_stringio.string -end -#puts lineInstructionsH - -lines = [] - -File.open("../../src/mx/core/Elements.h", "r") do |f| - f.each_line do |line| - lines << line - end -end - - - - -lineInstructionsH.each do |li| - File.open("../../src/mx/core/elements/#{li.name}.h", "w") do |f| - f << "// MusicXML Class Library v0.1.1" << "\n" - f << "// Copyright (c) 2015 - 2016 by Matthew James Briggs" << "\n" - f << "" << "\n" - f << "#pragma once" << "\n" - f << "" << "\n" - f << "#include \"mx/core/ForwardDeclare.h\"" << "\n" - - #includes - if li.inherits_from.eql? "AttributesInterface" - f << "#include \"mx/core/AttributesInterface.h\"" << "\n" - elsif li.inherits_from.eql? "ElementInterface" - f << "#include \"mx/core/ElementInterface.h\"" << "\n" - end - - #store the core code lines for reference - code = getCodeAsString li, lines - - decimals_symbols = listDecimals - f << includeIfNeeded( decimals_symbols, code, "mx/core/Decimals.h" ) - - enum_symbols = listEnums - enums_h_classes = listClassesInEnumsH - f << includeEnumsIfNeeded( enum_symbols, enums_h_classes, code ) - - integers_symbols = listIntegers - f << includeIfNeeded( integers_symbols, code, "mx/core/Integers.h" ) - - strings_symbols = listStrings - f << includeIfNeeded( strings_symbols, code, "mx/core/Strings.h" ) - - - - - f << includeStandaloneIfNeeded( "Color", code ) - f << includeStandaloneIfNeeded( "Date", code ) - f << includeStandaloneIfNeeded( "Document", code ) - f << includeStandaloneIfNeeded( "DocumentPartwise", code ) - f << includeStandaloneIfNeeded( "DocumentTimewise", code ) - f << includeStandaloneIfNeeded( "DocumentHeader", code ) - f << includeStandaloneIfNeeded( "DocumentSpec", code ) - f << includeStandaloneIfNeeded( "EmptyPrintObjectStyleAlignAttributes", code ) - f << includeStandaloneIfNeeded( "FontSize", code ) - f << includeStandaloneIfNeeded( "NumberOrNormal", code ) - f << includeStandaloneIfNeeded( "PositiveIntegerOrEmpty", code ) - f << includeStandaloneIfNeeded( "YesNoNumber", code ) - - - attribute_classes = listAttributeClasses - attribute_classes.each do |a| - f << includeOneIfNeeded( "#{a}Ptr", code, "mx/core/elements/#{a}.h" ) - end - - f << "\n" - f << "#include \n" - f << "#include \n" - f << "#include \n" - - - #element_classes = listElementClasses - #element_classes.each do |e| - # if !e.eql? li.name - # f << includeOneIfNeeded( "#{e}Ptr", code, "mx/core/elements/#{e}.h" ) - # end - #end - - - f << "" << "\n" - f << "namespace mx" << "\n" - f << "{" << "\n" - f << " namespace core" << "\n" - f << " {" << "\n" - f << "" << "\n" - - #forward declarations - attribute_classes = listAttributeClasses - if !li.inherits_from.eql? "AttributesInterface" - attribute_classes.each do |a| - if !a.eql? li.name - forwardDeclareAttributesIfNeeded( f, a, code ) - end - end - end - - element_classes = listElementClasses - element_classes.each do |e| - if !e.eql? li.name - forwardDeclareElementIfNeeded( f, e, code ) - end - end - - if li.inherits_from.eql? "ElementInterface" - forwardDeclareElementIfNeeded( f, li.name, code ) - end - - if li.inherits_from.eql? "AttributesInterface" - forwardDeclareAttributesIfNeeded( f, li.name, code ) - end - - f << "" << "\n" - f << code - #for i in li.declaration_line..li.end_line - # f << "#{lines[i]}" - #end - - f << " }" << "\n" - f << "}" << "\n" - end -end - -# one off stupid files for using statements -#elementsHUsingFile( "EditorialVoiceDirectionGroup", "EditorialVoiceGroup" ) -#elementsHUsingFile( "InvertedMordentAttributes", "MordentAttributes" ) -#elementsHUsingFile( "ToeAttributes", "HeelAttributes" ) diff --git a/gen/version-b/.gitignore b/gen/version-b/.gitignore deleted file mode 100644 index f6c313cef..000000000 --- a/gen/version-b/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/target -/data \ No newline at end of file diff --git a/gen/version-b/Cargo.lock b/gen/version-b/Cargo.lock deleted file mode 100644 index 21bd05125..000000000 --- a/gen/version-b/Cargo.lock +++ /dev/null @@ -1,705 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "aho-corasick" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8716408b8bc624ed7f65d223ddb9ac2d044c0547b6fa4b0d554f3a9540496ada" -dependencies = [ - "memchr", -] - -[[package]] -name = "ansi_term" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" -dependencies = [ - "winapi", -] - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi", -] - -[[package]] -name = "autocfg" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" - -[[package]] -name = "bitflags" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" - -[[package]] -name = "block-buffer" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" -dependencies = [ - "block-padding", - "byte-tools", - "byteorder", - "generic-array", -] - -[[package]] -name = "block-padding" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" -dependencies = [ - "byte-tools", -] - -[[package]] -name = "byte-tools" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" - -[[package]] -name = "byteorder" -version = "1.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" - -[[package]] -name = "cargo-readme" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66dbfc9307f5b2429656e07533613cd3f26803fd2857fc33be22aa2711181d58" -dependencies = [ - "clap", - "lazy_static", - "percent-encoding", - "regex", - "serde", - "serde_derive", - "toml", -] - -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - -[[package]] -name = "clap" -version = "2.33.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" -dependencies = [ - "ansi_term", - "atty", - "bitflags", - "strsim", - "textwrap 0.11.0", - "unicode-width", - "vec_map", -] - -[[package]] -name = "derive_more" -version = "0.99.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc655351f820d774679da6cdc23355a93de496867d8203496675162e17b1d671" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "digest" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" -dependencies = [ - "generic-array", -] - -[[package]] -name = "exile" -version = "0.0.2" -dependencies = [ - "cargo-readme", - "xdoc", - "xtest", -] - -[[package]] -name = "fake-simd" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" - -[[package]] -name = "generic-array" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" -dependencies = [ - "typenum", -] - -[[package]] -name = "getrandom" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "handlebars" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86dbc8a0746b08f363d2e00da48e6c9ceb75c198ac692d2715fcbb5bee74c87d" -dependencies = [ - "log", - "pest", - "pest_derive", - "quick-error", - "serde", - "serde_json", -] - -[[package]] -name = "heck" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "hermit-abi" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1010591b26bbfe835e9faeabeb11866061cc7dcebffd56ad7d0942d0e61aefd8" -dependencies = [ - "libc", -] - -[[package]] -name = "indexmap" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c398b2b113b55809ceb9ee3e753fcbac793f1956663f3c36549c1346015c2afe" -dependencies = [ - "autocfg", -] - -[[package]] -name = "itoa" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.67" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb147597cdf94ed43ab7a9038716637d2d1bf2bc571da995d0028dec06bd3018" - -[[package]] -name = "log" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "maplit" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" - -[[package]] -name = "memchr" -version = "2.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" - -[[package]] -name = "mxgen" -version = "0.1.0" -dependencies = [ - "derive_more", - "exile", - "handlebars", - "indexmap", - "lazy_static", - "serde", - "structopt", - "tempfile", - "textwrap 0.12.1", - "uuid", -] - -[[package]] -name = "opaque-debug" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" - -[[package]] -name = "percent-encoding" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" - -[[package]] -name = "pest" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" -dependencies = [ - "ucd-trie", -] - -[[package]] -name = "pest_derive" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0" -dependencies = [ - "pest", - "pest_generator", -] - -[[package]] -name = "pest_generator" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55" -dependencies = [ - "pest", - "pest_meta", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "pest_meta" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d" -dependencies = [ - "maplit", - "pest", - "sha-1", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea" - -[[package]] -name = "proc-macro-error" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7959c6467d962050d639361f7703b2051c43036d03493c36f01d440fdd3138a" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4002d9f55991d5e019fb940a90e1a95eb80c24e77cb2462dd4dc869604d543a" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "syn-mid", - "version_check", -] - -[[package]] -name = "proc-macro2" -version = "1.0.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12" -dependencies = [ - "unicode-xid", -] - -[[package]] -name = "quick-error" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" - -[[package]] -name = "quote" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom", - "libc", - "rand_chacha", - "rand_core", - "rand_hc", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core", -] - -[[package]] -name = "redox_syscall" -version = "0.1.56" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" - -[[package]] -name = "regex" -version = "1.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8900ebc1363efa7ea1c399ccc32daed870b4002651e0bed86e72d501ebbe0048" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", - "thread_local", -] - -[[package]] -name = "regex-syntax" -version = "0.6.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe5bd57d1d7414c6b5ed48563a2c855d995ff777729dcd91c369ec7fea395ae" - -[[package]] -name = "remove_dir_all" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" -dependencies = [ - "winapi", -] - -[[package]] -name = "ryu" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed3d612bc64430efeb3f7ee6ef26d590dce0c43249217bddc62112540c7941e1" - -[[package]] -name = "serde" -version = "1.0.114" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5317f7588f0a5078ee60ef675ef96735a1442132dc645eb1d12c018620ed8cd3" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.114" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0be94b04690fbaed37cddffc5c134bf537c8e3329d53e982fe04c374978f8e" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.53" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "993948e75b189211a9b31a7528f950c6adc21f9720b6438ff80a7fa2f864cea2" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_plain" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "625fb0da2b006092b426a94acc1611bec52f2ec27bb27b266a9f93c29ee38eda" -dependencies = [ - "serde", -] - -[[package]] -name = "sha-1" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df" -dependencies = [ - "block-buffer", - "digest", - "fake-simd", - "opaque-debug", -] - -[[package]] -name = "strsim" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" - -[[package]] -name = "structopt" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fe43617218c0805c6eb37160119dc3c548110a67786da7218d1c6555212f073" -dependencies = [ - "clap", - "lazy_static", - "structopt-derive", -] - -[[package]] -name = "structopt-derive" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6e79c80e0f4efd86ca960218d4e056249be189ff1c42824dcd9a7f51a56f0bd" -dependencies = [ - "heck", - "proc-macro-error", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "syn" -version = "1.0.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cdb98bcb1f9d81d07b536179c269ea15999b5d14ea958196413869445bb5250" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "syn-mid" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tempfile" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" -dependencies = [ - "cfg-if", - "libc", - "rand", - "redox_syscall", - "remove_dir_all", - "winapi", -] - -[[package]] -name = "textwrap" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", -] - -[[package]] -name = "textwrap" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "203008d98caf094106cfaba70acfed15e18ed3ddb7d94e49baec153a2b462789" -dependencies = [ - "unicode-width", -] - -[[package]] -name = "thread_local" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "toml" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" -dependencies = [ - "serde", -] - -[[package]] -name = "typenum" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" - -[[package]] -name = "ucd-trie" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" - -[[package]] -name = "unicode-segmentation" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" - -[[package]] -name = "unicode-width" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479" - -[[package]] -name = "unicode-xid" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" - -[[package]] -name = "uuid" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fde2f6a4bea1d6e007c4ad38c6839fa71cbb63b6dbf5b595aa38dc9b1093c11" -dependencies = [ - "rand", -] - -[[package]] -name = "vec_map" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" - -[[package]] -name = "version_check" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce" - -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - -[[package]] -name = "winapi" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "xdoc" -version = "0.0.2" -dependencies = [ - "cargo-readme", - "serde", -] - -[[package]] -name = "xtest" -version = "0.0.2" -dependencies = [ - "cargo-readme", - "serde", - "serde_json", - "serde_plain", - "xdoc", -] diff --git a/gen/version-b/Cargo.toml b/gen/version-b/Cargo.toml deleted file mode 100644 index c2240da9d..000000000 --- a/gen/version-b/Cargo.toml +++ /dev/null @@ -1,33 +0,0 @@ -[package] -name = "mxgen" -version = "0.1.0" -authors = ["Matthew James Briggs "] -edition = "2018" - -[[bin]] -name = "mxgen" -path = "src/bin/main.rs" - -[[bin]] -name = "show" -path = "src/bin/show.rs" - -[[bin]] -name = "flatten" -path = "src/bin/flatten.rs" - -[lib] -name = "libmxgen" -path = "src/lib.rs" - -[dependencies] -derive_more = "0.99.8" -exile = { version = "0.0.2", path = "/Users/mjb/repos/exile/exile" } -handlebars = "3.3.0" -indexmap = "1.4.0" -lazy_static = "1.4.0" -serde = "1.0.114" -structopt = "0.3.11" -tempfile = "3.1.0" -textwrap = "0.12.1" -uuid = { version = "0.8", features = ["v4"] } \ No newline at end of file diff --git a/gen/version-b/rustfmt.toml b/gen/version-b/rustfmt.toml deleted file mode 100644 index 169e7cb9e..000000000 --- a/gen/version-b/rustfmt.toml +++ /dev/null @@ -1,2 +0,0 @@ -#fn_call_width=10 does nothing? -#max_width=120 \ No newline at end of file diff --git a/gen/version-b/src/bin/flatten.rs b/gen/version-b/src/bin/flatten.rs deleted file mode 100644 index ddeeaf881..000000000 --- a/gen/version-b/src/bin/flatten.rs +++ /dev/null @@ -1,28 +0,0 @@ -use libmxgen::generate::paths::Paths; -use libmxgen::xsd::id::{Id, RootNodeType}; -use libmxgen::xsd::Xsd; - -const EXIT_SUCCESS: i32 = 0; -const EXIT_FAIL: i32 = 1; - -macro_rules! must { - ($result:expr) => { - match $result { - Err(e) => { - eprintln!("{}:{} {:?}", file!(), line!(), e); - std::process::exit(EXIT_FAIL); - } - Ok(o) => o, - } - }; -} - -fn main() { - let paths = Paths::default(); - let mut xsd = must!(Xsd::load(&paths.xsd_3_0)); - let id = Id::new(RootNodeType::Element, "score-partwise".to_owned()); - let found = must!(xsd.find(&id)).to_owned(); - let entity = must!(xsd.remove(found.id())); - println!("{:?}", &entity); - std::process::exit(EXIT_SUCCESS); -} diff --git a/gen/version-b/src/bin/main.rs b/gen/version-b/src/bin/main.rs deleted file mode 100644 index e867f18f7..000000000 --- a/gen/version-b/src/bin/main.rs +++ /dev/null @@ -1,16 +0,0 @@ -use libmxgen::generate::{run, GenArgs}; -use std::time::Instant; - -fn main() { - let start = Instant::now(); - let exit_code = match run(GenArgs::default()) { - Ok(()) => 0, - Err(err) => { - eprintln!("{}", err); - 1 - } - }; - let duration = start.elapsed(); - println!("Runtime: {:?}", duration); - std::process::exit(exit_code); -} diff --git a/gen/version-b/src/bin/show.rs b/gen/version-b/src/bin/show.rs deleted file mode 100644 index bf0f67cce..000000000 --- a/gen/version-b/src/bin/show.rs +++ /dev/null @@ -1,118 +0,0 @@ -use exile::Element; -use indexmap::set::IndexSet; -use libmxgen::generate::paths::Paths; -use std::collections::HashMap; - -fn main() { - let paths = Paths::default(); - let xml_str = std::fs::read_to_string(paths.xsd_3_0).unwrap(); - let doc = exile::parse(&xml_str).unwrap(); - let children_types = print_sequence_children(doc.root(), "choice"); - println!("=========================================================================================="); - println!("\nAll Subtypes:"); - for child_type in children_types { - println!("{}", child_type) - } -} - -#[allow(unused)] -fn find_xs_nodes(node: &exile::Element, xs_nodes: &mut IndexSet) { - if let Some(ns) = &node.namespace { - if ns == "xs" { - xs_nodes.insert(node.fullname()); - } - } - for child in node.children() { - find_xs_nodes(child, xs_nodes); - } -} - -#[allow(unused)] -fn print_group_children(root: &Element) { - println!("=========================================================================================="); - println!("GROUPS"); - println!("=========================================================================================="); - let mut the_stuf = HashMap::new(); - for child in root.children() { - if child.name.as_str() == "group" { - let name = child.attributes.map().get("name").unwrap().clone(); - let mut xs_nodes = IndexSet::::new(); - for xs_thingy in child.children() { - if xs_thingy.name.as_str() != "annotation" { - xs_nodes.insert(xs_thingy.fullname()); - } - } - the_stuf.insert(name, xs_nodes); - } - } - for (key, val) in the_stuf { - println!(""); - println!("{}:", key); - for x in val { - println!("{}", x); - } - } -} - -fn print_sequence_children(root: &Element, target_element: &str) -> IndexSet { - println!("=========================================================================================="); - println!("{}", target_element.to_uppercase()); - println!("=========================================================================================="); - let mut children_types: IndexSet = IndexSet::new(); - print_sequence_children_recursively(root, target_element, "", &mut children_types); - children_types -} - -fn print_sequence_children_recursively( - node: &Element, - target_element: &str, - parent_name: &str, - children_types: &mut IndexSet, -) { - let mut most_recent_name = parent_name.to_owned(); - if let Some(nm) = node.attributes.map().get("name") { - most_recent_name = nm.clone(); - } - let mut attributes = Vec::new(); - for (k, _) in node.attributes.map() { - attributes.push(k.clone()); - } - attributes.sort(); - if node.name.as_str() == target_element { - print_sequence_children_the_children_part( - node, - target_element, - most_recent_name.as_str(), - &attributes, - children_types, - ); - } else { - for child in node.children() { - print_sequence_children_recursively( - child, - target_element, - most_recent_name.as_str(), - children_types, - ); - } - } -} - -fn print_sequence_children_the_children_part( - node: &Element, - target_element: &str, - parent_name: &str, - attributes: &Vec, - children_types: &mut IndexSet, -) { - if node.name.as_str() != target_element { - panic!("wtf"); - } - println!(""); - println!("{}:", parent_name); - println!("[{}]", attributes.join(" ")); - for child in node.children() { - println!("{}", child.name.as_str()); - children_types.insert(child.name.clone()); - } -} diff --git a/gen/version-b/src/error.rs b/gen/version-b/src/error.rs deleted file mode 100644 index 9c23010e8..000000000 --- a/gen/version-b/src/error.rs +++ /dev/null @@ -1,186 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////////////////////////// -// public error type -//////////////////////////////////////////////////////////////////////////////////////////////////// - -use core::fmt; -use std::convert::Infallible; -use std::fmt::{Debug, Display, Formatter}; - -pub type Result = std::result::Result; - -pub enum Error { - Message(MessageError), -} - -impl Display for crate::error::Error { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - match self { - Error::Message(me) => Display::fmt(me, f), - } - } -} - -impl Debug for Error { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - Display::fmt(self, f) - } -} - -impl std::error::Error for crate::error::Error { - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - match self { - Error::Message(e) => { - if let Some(s) = &e.source { - Some(s.as_ref()) - } else { - None - } - } - } - } -} - -#[derive(Debug)] -pub struct MessageError { - pub throw_site: ThrowSite, - pub message: Option, - pub source: Option>, -} - -/// The Rust sourcecode file and line number which is the 'throw' site of an error. -#[derive(Debug, Clone, Eq, PartialOrd, PartialEq, Hash, Default)] -pub struct ThrowSite { - /// The rust source file where the error was thrown, i.e. file!() - pub file: String, - /// The rust source line number where the error was thrown, i.e. line!() - pub line: u32, -} - -impl Display for ThrowSite { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - write!(f, "{}:{}", self.file, self.line) - } -} - -impl Display for MessageError { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - // self.throw_site.fmt(f)?; - Display::fmt(&self.throw_site, f)?; - if let Some(msg) = &self.message { - if !msg.is_empty() { - write!(f, " - {}", msg)?; - } else { - write!(f, " - error")?; - } - } - if let Some(e) = &self.source { - write!(f, " - caused by: {}", e)?; - } - Ok(()) - } -} - -/// Not sure what this is for. -impl From for Error { - fn from(_: Infallible) -> Self { - unreachable!() - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// internal macros -//////////////////////////////////////////////////////////////////////////////////////////////////// - -pub fn box_err(err: Option) -> Option> -where - E: std::error::Error + 'static, -{ - match err { - None => None, - Some(e) => Some(e.into()), - } -} - -/// This macro is used internally to obtain the current file and line (in the sourcecode). -macro_rules! throw_site { - () => { - crate::error::ThrowSite { - file: file!().to_owned(), - line: line!(), - } - }; -} - -/// This macro is used internally to wrap a foreign Result type into a `crate::error::Result`. -/// The first argument is always a `Result`, and the second+ arguments are for format!() -macro_rules! wrap { - ($e:expr) => { - match $e { - Ok(value) => Ok(value), - Err(er) => { - Err(crate::error::Error::Message(crate::error::MessageError{ - throw_site: throw_site!(), - message: Some("error".into()), - source: crate::error::box_err(Some(er)), - })) - } - } - }; - ($e:expr, $msg:expr) => { - match $e { - Ok(value) => Ok(value), - Err(er) => { - Err(crate::error::Error::Message(crate::error::MessageError{ - throw_site: throw_site!(), - message: Some($msg.into()), - source: crate::error::box_err(Some(er)), - })) - } - } - }; - ($e:expr, $fmt:expr, $($arg:expr),+) => { - match $e { - Ok(value) => Ok(value), - Err(er) => { - Err(crate::error::Error::Message(crate::error::MessageError{ - throw_site: throw_site!(), - message: Some(format!($fmt, $($arg),+)), - source: crate::error::box_err(Some(er)), - })) - } - } - }; -} - -/// This macro is used internally to create an `Err(crate::error::Error::Message)`. -macro_rules! make_err { - () => { - crate::error::Error::Message(crate::error::MessageError{ - throw_site: throw_site!(), - message: Option::::None, - source: Option::::None, - }) - }; - ($msg:expr) => { - crate::error::Error::Message(crate::error::MessageError{ - throw_site: throw_site!(), - message: Some($msg.into()), - source: Option::>::None, - }) - }; - ($fmt:expr, $($arg:expr),+) => { - crate::error::Error::Message(crate::error::MessageError{ - throw_site: throw_site!(), - message: Some(format!($fmt, $($arg),+)), - source: Option::>::None, - }) - }; -} - -macro_rules! raise { - ($($x:tt)*) => { - { - Err(make_err!($($x)*)) - } - } -} diff --git a/gen/version-b/src/generate/compile_mx.rs b/gen/version-b/src/generate/compile_mx.rs deleted file mode 100644 index 58e7f8acf..000000000 --- a/gen/version-b/src/generate/compile_mx.rs +++ /dev/null @@ -1,49 +0,0 @@ -use crate::error::Result; -use std::fs::{read_to_string, File}; -use std::path::Path; -use std::process::{Command, Output, Stdio}; -use tempfile::TempDir; -use uuid::Uuid; - -#[allow(unused)] -pub fn compile_mx>(path_to_mx: P) -> Result<()> { - let tempdir = wrap!(TempDir::new())?; - let _ = run( - Command::new("cmake") - .arg(path_to_mx.as_ref()) - .arg("-DMX_BUILD_TESTS=on") - .arg("-DMX_BUILD_EXAMPLES=on") - .arg("-DMX_BUILD_CORE_TESTS=off"), - tempdir.path(), - )?; - let _ = run(Command::new("make").arg("-j9"), tempdir.path())?; - run_mx_tests(tempdir.path())?; - Ok(()) -} - -#[allow(unused)] -fn run_mx_tests>(path: P) -> Result<()> { - let _ = run(&mut Command::new("./mxtest"), path.as_ref())?; - Ok(()) -} - -#[allow(unused)] -fn run>(cmd: &mut Command, dir: P) -> Result<(String, Output)> { - let u = Uuid::new_v4(); - let opath = dir.as_ref().join(format!("combined_output.log.{}", u)); - let ofile = wrap!(File::create(&opath))?; - let efile = wrap!(ofile.try_clone())?; - let result = wrap!(cmd - .current_dir(&dir.as_ref()) - .stdout(Stdio::from(ofile)) - .stderr(Stdio::from(efile)) - .spawn())? - .wait_with_output(); - let output = wrap!(result)?; - let outstr = wrap!(read_to_string(&opath))?; - if !output.status.success() { - return raise!("Command failed '{:?}':\n{}", &cmd, outstr); - } - println!("Command output '{:?}':\n{}", &cmd, outstr); - Ok((outstr, output)) -} diff --git a/gen/version-b/src/generate/cpp/constants.rs b/gen/version-b/src/generate/cpp/constants.rs deleted file mode 100644 index 48e2cf006..000000000 --- a/gen/version-b/src/generate/cpp/constants.rs +++ /dev/null @@ -1,168 +0,0 @@ -use indexmap::set::IndexSet; -use std::collections::HashMap; - -/// Returns a list of simple-type enumeration values that are mapped to something different in the -/// generated code. -pub fn enum_member_substitutions() -> HashMap { - let mut substitutions = HashMap::new(); - // for better or worse, i chose to map these enum members that start with numbers like so... - substitutions.insert("16th".to_string(), "sixteenth".to_string()); - substitutions.insert("32nd".to_string(), "thirtySecond".to_string()); - substitutions.insert("64th".to_string(), "sixtyFourth".to_string()); - substitutions.insert("128th".to_string(), "oneHundredTwentyEighth".to_string()); - substitutions.insert("256th".to_string(), "twoHundredFifthySixth".to_string()); - substitutions.insert("512th".to_string(), "fiveHundredTwelfth".to_string()); - substitutions.insert("1024th".to_string(), "oneThousandTwentyFourth".to_string()); - substitutions -} - -/// Returns a list of enums that I added the word 'Enum' to suffix the name. In some cases this was -/// to prevent a name clash with a complex-type or element by the same name. In other cases this was -/// because I wanted to 'wrap' the enum in a custom class (i.e. when the usage in MusicXML allows -/// for an 'other' string field. These are given as uppercase, as in `Something` where the resulting -/// code will be `enum class SomethingEnum`. -pub fn suffixed_enum_names() -> IndexSet { - // TODO - this list can probably be computed by observing the name conflicts in the XSD. - let mut names = IndexSet::new(); - names.insert("ArrowDirection".into()); - names.insert("ArrowStyle".into()); - names.insert("BarStyle".into()); - names.insert("CircularArrow".into()); - names.insert("DistanceType".into()); - names.insert("Effect".into()); - names.insert("Glass".into()); - names.insert("LineWidthType".into()); - names.insert("Membrane".into()); - names.insert("Metal".into()); - names.insert("Mode".into()); - names.insert("Mute".into()); - names.insert("Pitched".into()); - names.insert("Step".into()); - names.insert("Syllabic".into()); - names.insert("TimeRelation".into()); - names.insert("StickLocation".into()); - names.insert("StickMaterial".into()); - names.insert("StickType".into()); - names.insert("Wood".into()); - names.insert("SemiPitched".into()); - names.insert("StaffType".into()); - names -} - -/// Similar to the enums above, some simple types are suffixed by 'value' -pub fn suffixed_value_names() -> HashMap { - let mut names = HashMap::new(); - names.insert( - "accordion-middle".to_owned(), - "accordion-middle-value".to_owned(), - ); - names.insert("fifths".to_owned(), "fifths-value".to_owned()); - names.insert("octave".to_owned(), "octave-value".to_owned()); - names.insert("tenths".to_owned(), "tenths-value".to_owned()); - names.insert("divisions".to_owned(), "divisions-value".to_owned()); - names.insert("millimeters".to_owned(), "millimeters-value".to_owned()); - names.insert( - "positive-divisions".to_owned(), - "positive-divisions-value".to_owned(), - ); - names -} - -/// Returns a list of C++ keywords, to be used to avoid conflict with MusicXML names. -pub fn reserved_words() -> IndexSet { - let mut keywords = IndexSet::new(); - keywords.insert("continue".into()); - keywords.insert("do".into()); - keywords.insert("double".into()); - keywords.insert("explicit".into()); - keywords.insert("long".into()); - keywords.insert("short".into()); - keywords.insert("while".into()); - keywords -} - -#[derive(Debug, Clone)] -pub struct PseudoEnumSpec { - pub members: Vec, - /// The name of the field that is added to the enum, which can hold any value. - pub extra_field_name: String, - /// The name of the class which "wraps" the enum with the ability to hold an arbitrary string. - pub class_name: String, - /// The enum value when the wrapper class is default constructed. - pub default_value: String, -} - -/// e.g. `line-width-type` and `distance-type` which give enum values in the documentation but do -/// not restrict the string via xsd. In this case we have extracted the enum values from the -/// documentation by hand and use an `other` 'variant' to hold any string other than those listed. -pub fn pseudo_enums() -> HashMap { - let mut map = HashMap::new(); - map.insert( - "simpleType:distance-type".to_owned(), - PseudoEnumSpec { - members: vec!["beam".to_owned(), "hyphen".to_owned()], - extra_field_name: "other".to_owned(), - class_name: "DistanceType".to_owned(), - default_value: "beam".to_owned(), - }, - ); - map.insert( - "simpleType:line-width-type".to_owned(), - PseudoEnumSpec { - members: vec![ - "beam".to_owned(), - "bracket".to_owned(), - "dashes".to_owned(), - "enclosure".to_owned(), - "ending".to_owned(), - "extend".to_owned(), - "heavy barline".to_owned(), - "leger".to_owned(), - "light barline".to_owned(), - "octave shift".to_owned(), - "pedal".to_owned(), - "slur middle".to_owned(), - "slur tip".to_owned(), - "staff".to_owned(), - "stem".to_owned(), - "tie middle".to_owned(), - "tie tip".to_owned(), - "tuplet bracket".to_owned(), - "wedge".to_owned(), - ], - extra_field_name: "other".to_owned(), - class_name: "LineWidthType".to_owned(), - default_value: "beam".to_owned(), - }, - ); - map.insert( - "simpleType:mode".to_owned(), - PseudoEnumSpec { - members: vec![ - "major".to_owned(), - "minor".to_owned(), - "dorian".to_owned(), - "phrygian".to_owned(), - "lydian".to_owned(), - "mixolydian".to_owned(), - "aeolian".to_owned(), - "ionian".to_owned(), - "locrian".to_owned(), - "none".to_owned(), - ], - extra_field_name: "other".to_owned(), - class_name: "ModeValue".to_owned(), - default_value: "major".to_owned(), - }, - ); - map -} - -pub fn custom_scalar_strings() -> IndexSet<&'static str> { - let mut set = IndexSet::new(); - set.insert("comma-separated-text"); - set.insert("color"); - set.insert("time-only"); - set.insert("ending-number"); - set -} diff --git a/gen/version-b/src/generate/cpp/cpp_template.rs b/gen/version-b/src/generate/cpp/cpp_template.rs deleted file mode 100644 index b11365653..000000000 --- a/gen/version-b/src/generate/cpp/cpp_template.rs +++ /dev/null @@ -1,90 +0,0 @@ -use crate::error::Result; -use crate::generate::template; -use crate::generate::template::{render, CORE_CPP, CORE_H}; -use std::borrow::Cow; -use std::collections::HashMap; - -pub(super) fn render_core_h( - contents: S, - lib_includes: Option<&mut [&str]>, - std_includes: Option<&mut [&str]>, -) -> Result -where - S: AsRef, -{ - let mut map = HashMap::new(); - if let Some(includes) = lib_includes { - if !includes.is_empty() { - includes.sort(); - let mut rendered = String::new(); - rendered.push('\n'); - for include in includes { - rendered.push('\n'); - rendered.push_str(format!("#include \"{}\"", include).as_str()); - } - map.insert("lib_includes", rendered); - } - } - if let Some(includes) = std_includes { - if !includes.is_empty() { - includes.sort(); - let mut rendered = String::new(); - rendered.push('\n'); - for include in includes { - rendered.push('\n'); - rendered.push_str(format!("#include <{}>", include).as_str()); - } - map.insert("std_includes", rendered); - } - } - map.insert("contents", contents.as_ref().to_owned()); - render(CORE_H, &map) -} - -pub(super) fn render_core_cpp( - contents: S1, - self_include: Option, - lib_includes: Option<&mut [&str]>, - std_includes: Option<&mut [&str]>, -) -> Result -where - S1: AsRef, - S2: AsRef, -{ - let mut map = HashMap::new(); - if self_include.is_some() || lib_includes.is_some() || std_includes.is_some() { - map.insert("lead_whitespace", "\n\n".to_owned()); - } - if let Some(include) = self_include { - let include = include.as_ref(); - let mut rendered = String::new(); - rendered.push_str(format!("// self\n#include \"{}\"", include).as_str()); - map.insert("self_include", rendered); - } - if let Some(includes) = lib_includes { - if !includes.is_empty() { - includes.sort(); - let mut rendered = String::new(); - rendered.push_str("\n\n// lib"); - for include in includes { - rendered.push('\n'); - rendered.push_str(format!("#include \"{}\"", include).as_str()); - } - map.insert("lib_includes", rendered); - } - } - if let Some(includes) = std_includes { - if !includes.is_empty() { - includes.sort(); - let mut rendered = String::new(); - rendered.push_str("\n\n// std"); - for include in includes { - rendered.push('\n'); - rendered.push_str(format!("#include <{}>", include).as_str()); - } - map.insert("std_includes", rendered); - } - } - map.insert("contents", contents.as_ref().to_owned()); - render(CORE_CPP, &map) -} diff --git a/gen/version-b/src/generate/cpp/helpers.rs b/gen/version-b/src/generate/cpp/helpers.rs deleted file mode 100644 index de466c545..000000000 --- a/gen/version-b/src/generate/cpp/helpers.rs +++ /dev/null @@ -1,14 +0,0 @@ -use crate::error::Result; -use crate::model::enumeration::Enumeration; -use crate::model::Def; - -pub(super) fn enum_default(e: &Enumeration) -> String { - format!("{}::{}", e.name.pascal(), e.default.camel()) -} - -pub(super) fn default_construct(d: &Def) -> String { - match d { - Def::Enumeration(e) => enum_default(e), - _ => format!("{}::{{}}", d.name().pascal()), - } -} diff --git a/gen/version-b/src/generate/cpp/mod.rs b/gen/version-b/src/generate/cpp/mod.rs deleted file mode 100644 index e281246cc..000000000 --- a/gen/version-b/src/generate/cpp/mod.rs +++ /dev/null @@ -1,19 +0,0 @@ -pub mod constants; -mod cpp_template; -mod helpers; -pub mod modeler; -mod write_custom; -mod write_enums; -mod write_numerics; -mod write_unions; -pub mod writer; - -use crate::error::Result; -use std::path::Path; - -fn check_file_exists>(path: P) -> Result<()> { - if !path.as_ref().is_file() { - return raise!("Expected file at '{}'", path.as_ref().display()); - } - Ok(()) -} diff --git a/gen/version-b/src/generate/cpp/modeler.rs b/gen/version-b/src/generate/cpp/modeler.rs deleted file mode 100644 index f4229c8d4..000000000 --- a/gen/version-b/src/generate/cpp/modeler.rs +++ /dev/null @@ -1,357 +0,0 @@ -use crate::generate::cpp::constants::{ - custom_scalar_strings, enum_member_substitutions, pseudo_enums, reserved_words, - suffixed_enum_names, suffixed_value_names, PseudoEnumSpec, -}; -use crate::model; -use crate::model::builtin::BuiltinString; -use crate::model::create::{Create, CreateError, CreateResult}; -use crate::model::enumeration::OtherField; -use crate::model::post_process::PostProcess; -use crate::model::scalar::{Bound, NumericData, Range, ScalarNumeric}; -use crate::model::symbol::Symbol; -use crate::model::transform::Transform; -use crate::model::Def::Enumeration; -use crate::model::{Def, DefaultCreate}; -use crate::xsd::choice::{Choice, ChoiceItem}; -use crate::xsd::complex_type::{Children, ComplexType, Parent}; -use crate::xsd::element::{ElementDef, ElementRef}; -use crate::xsd::id::{Id, RootNodeType}; -use crate::xsd::primitives::Numeric; -use crate::xsd::primitives::{BaseType, Character, PrefixedString, Primitive}; -use crate::xsd::restriction::Facet; -use crate::xsd::{complex_type, element, simple_type, Entry, Xsd}; -use indexmap::set::IndexSet; -use std::collections::HashMap; - -#[derive(Debug, Clone)] -pub struct MxModeler { - enum_member_substitutions: HashMap, - suffixed_enum_names: IndexSet, - suffixed_value_names: HashMap, - reserved_words: IndexSet, - pseudo_enums: HashMap, - custom_scalar_strings: IndexSet<&'static str>, -} - -impl Transform for MxModeler { - fn name(&self) -> &'static str { - "mx-cpp" - } - - fn transform(&self, entry: &Entry, xsd: &Xsd) -> Result { - let mut cloned = entry.clone(); - if let Entry::SimpleType(st) = &mut cloned { - let symbolized = Symbol::new(st.name.as_str()); - if self.suffixed_enum_names.contains(symbolized.pascal()) { - st.name.push_str("-enum"); - } - } - Ok(cloned) - } -} - -impl Create for MxModeler { - fn name(&self) -> &'static str { - "mx-cpp" - } - - fn create(&self, entry: &Entry, xsd: &Xsd) -> CreateResult { - if let Some(spec) = self.pseudo_enums.get(entry.id().display().as_str()) { - return create_pseudo_enum(entry, spec); - } - if let Id::Root(rid) = entry.id() { - if rid.type_() == RootNodeType::ComplexType { - if rid.name().as_ref() == "dynamics" { - return self.create_dynamics(entry); - } - } - } - Ok(None) - } -} - -impl PostProcess for MxModeler { - fn name(&self) -> &'static str { - "mx-cpp" - } - - fn process(&self, model: &Def, xsd: &Xsd) -> Result { - if let Def::Enumeration(enumer) = model { - let mut cloned = enumer.clone(); - for (i, member) in cloned.members.iter_mut().enumerate() { - // add an underscore as a suffix to camel case representations that would otherwise - // collide with reserved words in C++. - if self.reserved_words.contains(member.camel()) { - let mut replacement = member.camel().to_owned(); - replacement.push('_'); - member.set_camel(replacement) - } - // replace certain enum representations that would be illegal in C++, e.g. 16th. - if let Some(replacement) = self.enum_member_substitutions.get(member.original()) { - member.replace(replacement); - } - // replace an empty string value with some kind of symbol name. - if member.original() == "" { - member.replace("emptystring"); - } - if i == 0 && member.original() == cloned.default.original() { - if member.renamed_to() != cloned.default.renamed_to() { - cloned.default.replace(member.renamed_to()); - } - if member.camel() != cloned.default.camel() { - cloned.default.set_camel(member.camel()); - } - } - } - return Ok(Def::Enumeration(cloned)); - } else if let Def::ScalarString(scalar_string) = model { - if self - .custom_scalar_strings - .contains(scalar_string.name.original()) - { - return Ok(Def::CustomScalarString(scalar_string.clone())); - } else if let Some(new_name) = - self.suffixed_value_names.get(scalar_string.name.original()) - { - let mut st = scalar_string.clone(); - st.name.replace(&new_name); - return Ok(Def::ScalarString(st)); - } - } else if let Def::ScalarNumber(scalar_number) = model { - match scalar_number { - ScalarNumeric::Decimal(n) => { - if let Some(new_name) = self.suffixed_value_names.get(n.name.original()) { - let mut n = n.clone(); - n.name.replace(&new_name); - return Ok(Def::ScalarNumber(ScalarNumeric::Decimal(n))); - } - } - ScalarNumeric::Integer(n) => { - let mut is_changed = false; - let n = if n.name.original() == "accordion-middle" { - let mut changed = n.clone(); - changed.range.min = Some(Bound::Inclusive(0)); - changed.documentation.push_str( - "\n\nNote: MusicXML specifies the minimum allowable value \ - as 1, however test documents exist that have a value of 0. This library supports \ - a minimum value of 0. Per https://github.com/w3c/musicxml/issues/134, the correct \ - representation for 0 dots is to omit the element, so it is possible to create \ - invalid MusicXML by setting the value to 0 here.", - ); - is_changed = true; - changed - } else { - n.clone() - }; - // note: accordion-middle is one of the values that is renamed here. if it were - // not, it would need to be explicitly returned. - if let Some(new_name) = self.suffixed_value_names.get(n.name.original()) { - is_changed = true; - let mut mut_num = n.clone(); - mut_num.name.replace(&new_name); - return Ok(Def::ScalarNumber(ScalarNumeric::Integer(mut_num))); - } - } - } - } else if let Def::DerivedSimpleType(derived) = model { - match derived.name.original() { - "positive-divisions" => { - let replacement = NumericData { - name: derived.name.clone(), - base_type: Numeric::Decimal, - documentation: derived.documentation.clone(), - range: Range { - min: Some(Bound::Exclusive(0.0)), - max: None, - }, - }; - return Ok(Def::ScalarNumber(ScalarNumeric::Decimal(replacement))); - } - unhandled => { - return Err(CreateError { - message: format!("Unhandled DerivedSimpleType: '{}'", unhandled), - }) - } - } - } - Ok(model.clone()) - } -} - -impl MxModeler { - pub fn new() -> Self { - Self { - enum_member_substitutions: enum_member_substitutions(), - suffixed_enum_names: suffixed_enum_names(), - suffixed_value_names: suffixed_value_names(), - reserved_words: reserved_words(), - pseudo_enums: pseudo_enums(), - custom_scalar_strings: custom_scalar_strings(), - } - } - - fn create_dynamics(&self, entry: &Entry) -> CreateResult { - let (ct, p, choice) = self.unwrap_dynamics(entry)?; - let mut enumer = model::enumeration::Enumeration { - /// TODO - get the name in a generic manner - name: Symbol::new("dynamics enum"), - members: vec![], - documentation: entry.documentation(), - default: Symbol::new("mf"), - other_field: None, - }; - for c in &choice.choices { - let mut is_other_field_found = false; - if let Some(name) = self.unwrap_empty_element(c)? { - enumer.members.push(Symbol::new(name)); - } else { - let other_field_name = self.unwrap_other_field(c)?; - if enumer.other_field.is_some() { - return Err(CreateError { - message: "create_dynamics: multiple 'other' fields found".to_string(), - }); - } - enumer.other_field = Some(OtherField { - name: Symbol::new(other_field_name), - type_: BuiltinString::String, - wrapper_class_name: Symbol::new("dynamics value"), - }) - } - } - // TODO - also create the 'wrapping' element named 'dynamics' - Ok(Some(vec![Def::Enumeration(enumer)])) - } - - fn unwrap_dynamics<'a>( - &self, - entry: &'a Entry, - ) -> std::result::Result<(&'a ComplexType, &'a Parent, &'a Choice), CreateError> { - let ct = if let Entry::ComplexType(ct) = entry { - ct - } else { - return Err(CreateError { - message: "create_dynamics: wrong type".to_string(), - }); - }; - let p = if let complex_type::Payload::Parent(p) = &ct.payload { - p - } else { - return Err(CreateError { - message: "create_dynamics: expected parent".to_string(), - }); - }; - let children = if let Some(children) = &p.children { - children - } else { - return Err(CreateError { - message: "create_dynamics: expected children".to_string(), - }); - }; - let choice = if let Children::Choice(choice) = children { - choice - } else { - return Err(CreateError { - message: "create_dynamics: expected choice".to_string(), - }); - }; - Ok((ct, p, choice)) - } - - fn unwrap_empty_element<'a>( - &self, - c: &'a ChoiceItem, - ) -> std::result::Result, CreateError> { - let ref_: &ElementRef = if let ChoiceItem::Element(wrapped) = c { - let ref_ = if let element::Element::Reference(ref_) = wrapped { - ref_ - } else { - return Err(CreateError { - message: "unwrap_empty_element: expected ElementDef".to_string(), - }); - }; - ref_ - } else { - return Err(CreateError { - message: "unwrap_empty_element: expected Element".to_string(), - }); - }; - - if ref_.type_ == BaseType::Custom("empty".to_owned()) { - Ok(Some(ref_.name.as_str())) - } else { - Ok(None) - } - } - - fn unwrap_simple_element<'a>( - &self, - c: &'a ChoiceItem, - ) -> std::result::Result, CreateError> { - let ref_: &ElementRef = if let ChoiceItem::Element(wrapped) = c { - let ref_ = if let element::Element::Reference(ref_) = wrapped { - ref_ - } else { - return Err(CreateError { - message: "unwrap_empty_element: expected ElementDef".to_string(), - }); - }; - ref_ - } else { - return Err(CreateError { - message: "unwrap_empty_element: expected Element".to_string(), - }); - }; - - /// TODO - allow all base types? - if ref_.type_.is_string() || ref_.type_.is_token() { - Ok(Some((ref_.name.as_str(), &ref_.type_))) - } else { - Ok(None) - } - } - - fn unwrap_other_field<'a>( - &self, - c: &'a ChoiceItem, - ) -> std::result::Result<&'a str, CreateError> { - let found_stuff = if let Some(other_field) = self.unwrap_simple_element(c)? { - other_field - } else { - return Err(CreateError { - message: "create_dynamics: unable to unwrap the 'other' field".to_string(), - }); - }; - if *found_stuff.1 != BaseType::String { - return return Err(CreateError { - message: format!( - "unwrap_other_field: unsupported 'other' field type '{}'", - found_stuff.1.name() - ), - }); - } - Ok(found_stuff.0) - } -} - -fn create_pseudo_enum(entry: &Entry, spec: &PseudoEnumSpec) -> CreateResult { - let original = entry.id().name(); - let rename = format!("{}-enum", original); - let mut symbol = Symbol::new(original); - symbol.replace(rename); - let mut enumer = model::enumeration::Enumeration { - name: symbol, - members: vec![], - documentation: entry.documentation(), - default: Symbol::new(spec.default_value.as_str()), - other_field: Some(OtherField { - name: Symbol::new(spec.extra_field_name.as_str()), - // TODO - check if it's actually xs:token - type_: BuiltinString::String, - wrapper_class_name: Symbol::new(spec.class_name.as_str()), - }), - }; - for s in &spec.members { - enumer.members.push(Symbol::new(s.as_str())); - } - Ok(Some(vec![Def::Enumeration(enumer)])) -} diff --git a/gen/version-b/src/generate/cpp/write_custom.rs b/gen/version-b/src/generate/cpp/write_custom.rs deleted file mode 100644 index cdfe2c5a1..000000000 --- a/gen/version-b/src/generate/cpp/write_custom.rs +++ /dev/null @@ -1,43 +0,0 @@ -use crate::error::Result; -use crate::generate::cpp::check_file_exists; -use crate::generate::paths::Paths; -use crate::model::scalar::ScalarString; - -pub(super) fn write_color(model: &ScalarString, paths: &Paths) -> Result<()> { - if model.name.original() != "color" { - return raise!("expected 'color' got '{}'", model.name.original()); - } - check_file_exists(paths.core.join("Color.h"))?; - check_file_exists(paths.core.join("Color.cpp"))?; - Ok(()) -} - -pub(super) fn write_comma_separated_text(model: &ScalarString, paths: &Paths) -> Result<()> { - let expected = "comma-separated-text"; - if model.name.original() != expected { - return raise!("expected '{}' got '{}'", expected, model.name.original()); - } - check_file_exists(paths.core.join("CommaSeparatedText.h"))?; - check_file_exists(paths.core.join("CommaSeparatedText.cpp"))?; - Ok(()) -} - -pub(super) fn write_time_only(model: &ScalarString, paths: &Paths) -> Result<()> { - let expected = "time-only"; - if model.name.original() != expected { - return raise!("expected '{}' got '{}'", expected, model.name.original()); - } - check_file_exists(paths.core.join("TimeOnly.h"))?; - // no cpp file, alias only - Ok(()) -} - -pub(super) fn write_ending_number(model: &ScalarString, paths: &Paths) -> Result<()> { - let expected = "ending-number"; - if model.name.original() != expected { - return raise!("expected '{}' got '{}'", expected, model.name.original()); - } - check_file_exists(paths.core.join("TimeOnly.h"))?; - // no cpp file, alias only - Ok(()) -} diff --git a/gen/version-b/src/generate/cpp/write_enums.rs b/gen/version-b/src/generate/cpp/write_enums.rs deleted file mode 100644 index 6bf11543f..000000000 --- a/gen/version-b/src/generate/cpp/write_enums.rs +++ /dev/null @@ -1,188 +0,0 @@ -use crate::error::Result; -use crate::generate::cpp::cpp_template::{render_core_cpp, render_core_h}; -use crate::generate::cpp::writer::Writer; -use crate::generate::template::{render, ENUM_CPP, ENUM_H, ENUM_WRAPPER_CPP, ENUM_WRAPPER_H}; -use crate::model::enumeration::{Enumeration, OtherField}; -use crate::model::Def; -use crate::utils::string_stuff::{ - camel_case, documentation, linestart, pascal_case, sep, write_documentation, Altered, Symbol, -}; -use indexmap::set::IndexSet; -use std::collections::HashMap; -use std::fs::OpenOptions; -use std::io::Write; - -pub fn write_tabs(w: &mut W, num: u32) -> std::io::Result<()> { - for _ in 0..num { - write!(w, " ")?; - } - Ok(()) -} - -macro_rules! w { - ($w:expr, $tabs:expr, $($arg:expr),+) => {{ - crate::generate::cpp::write_enums::write_tabs($w, $tabs)?; - write!($w, $($arg),+) - }}; -} - -macro_rules! l { - ($w:expr, $tabs:expr, $($arg:expr),+) => {{ - crate::generate::cpp::write_enums::write_tabs($w, $tabs)?; - writeln!($w, $($arg),+) - }}; -} - -impl Writer { - pub(crate) fn write_enums(&self, enumerations: &mut [&Enumeration]) -> Result<()> { - enumerations.sort_by(|&a, &b| { - let a = a.name.pascal(); - let b = b.name.pascal(); - a.cmp(b) - }); - let mut contents_h = String::new(); - let mut contents_cpp = String::new(); - for (i, enumeration) in enumerations.iter().enumerate() { - let enumeration = *enumeration; - let first = i == 0; - let mut data = HashMap::new(); - data.insert("classname", enumeration.name.pascal().to_owned()); - data.insert("banner", sep(enumeration.name.pascal(), 2)); - data.insert( - "documentation", - documentation(&enumeration.documentation, 2)?, - ); - data.insert("enum_members_declare", enum_members_declare(enumeration)); - data.insert("enum_members_parse", enum_members_parse(enumeration)); - data.insert( - "enum_members_to_string", - enum_members_to_string(enumeration), - ); - if let Some(of) = &enumeration.other_field { - data.insert("default_value_enum", enumeration.default.camel().into()); - data.insert( - "default_value_string", - enumeration.default.original().into(), - ); - data.insert("to_string_default_return", of.name.original().into()); - data.insert("other_field_name", of.name.camel().into()); - } else { - let first_member = enumeration.members.first().unwrap(); - data.insert("default_value_enum", enumeration.default.camel().into()); - data.insert( - "default_value_string", - enumeration.default.original().into(), - ); - data.insert( - "to_string_default_return", - enumeration.default.original().into(), - ); - } - let rendered_h = render(ENUM_H, &data)?; - if !first { - contents_h.push('\n'); - contents_h.push('\n'); - } - contents_h.push_str(&rendered_h); - let rendered_cpp = render(ENUM_CPP, &data)?; - if !first { - contents_cpp.push('\n'); - contents_cpp.push('\n'); - } - contents_cpp.push_str(&rendered_cpp); - if let Some(of) = &enumeration.other_field { - data.insert("wrapper_classname", of.wrapper_class_name.pascal().into()); - contents_h.push_str("\n\n"); - contents_cpp.push_str("\n\n"); - contents_h.push_str(render(ENUM_WRAPPER_H, &data)?.as_str()); - contents_cpp.push_str(render(ENUM_WRAPPER_CPP, &data)?.as_str()); - } - } - let file_h = render_core_h( - contents_h, - Some(&mut ["mx/core/EnumsBuiltin.h"]), - Some(&mut ["iostream", "string", "optional"]), - )?; - let file_cpp = render_core_cpp( - contents_cpp, - Some("mx/core/Enums.h"), - None, - Some(&mut ["sstream"]), - )?; - wrap!(std::fs::write(&self.paths.enums_h, file_h))?; - wrap!(std::fs::write(&self.paths.enums_cpp, file_cpp))?; - Ok(()) - } -} - -fn enum_members_declare(e: &Enumeration) -> String { - let mut s = String::new(); - for (i, m) in e.members.iter().enumerate() { - s.push_str(format!(" {} = {}", m.camel(), i).as_str()); - if i < e.members.len() - 1 || e.other_field.is_some() { - s.push(','); - s.push('\n'); - } - } - if let Some(of) = &e.other_field { - s.push_str(format!(" {} = {}", of.name.camel(), e.members.len()).as_str()); - } - s -} - -fn enum_members_parse(e: &Enumeration) -> String { - let mut s = String::new(); - for (i, m) in e.members.iter().enumerate() { - let first = i == 0; - if !first { - s.push('\n'); - } - s.push_str(" "); - if !first { - s.push_str("else "); - } - s.push_str( - format!( - "if( value == \"{}\" ) {{ return {}::{}; }}", - m.original(), - e.name.pascal(), - m.camel() - ) - .as_str(), - ); - } - if let Some(of) = &e.other_field { - s.push_str("\n else "); - s.push_str( - format!( - "if( value == \"{}\" ) {{ return {}::{}; }}", - of.name.original(), - e.name.pascal(), - of.name.camel() - ) - .as_str(), - ); - } - s -} - -fn enum_members_to_string(e: &Enumeration) -> String { - let mut s = String::new(); - s.push_str(" switch ( value )\n"); - s.push_str(" {\n"); - for (i, m) in e.members.iter().enumerate() { - s.push_str(" "); - s.push_str( - format!( - "case {}::{}: {{ return \"{}\"; }}\n", - e.name.pascal(), - m.camel(), - m.original() - ) - .as_str(), - ); - } - s.push_str(" default: break;\n"); - s.push_str(" }"); - s -} diff --git a/gen/version-b/src/generate/cpp/write_numerics.rs b/gen/version-b/src/generate/cpp/write_numerics.rs deleted file mode 100644 index 2997df58e..000000000 --- a/gen/version-b/src/generate/cpp/write_numerics.rs +++ /dev/null @@ -1,323 +0,0 @@ -use crate::error::Result; -use crate::generate::cpp::cpp_template::{render_core_cpp, render_core_h}; -use crate::generate::cpp::writer::Writer; -use crate::generate::template::{ - render, CORE_H, DECIMAL_BUILTINS_CPP, DECIMAL_BUILTINS_H, DECIMAL_TYPE_CPP, DECIMAL_TYPE_H, - INTEGER_BUILTINS_CPP, INTEGER_BUILTINS_H, INTEGER_TYPE_CPP, INTEGER_TYPE_H, NO_DATA, -}; -use crate::model::scalar::{Bound, NumericData, Range}; -use crate::model::scalar::{ScalarNumeric, ScalarString}; -use crate::model::symbol::Symbol; -use crate::model::Def; -use crate::utils::string_stuff::{documentation, sep, write_documentation}; -use crate::xsd::primitives::BaseType; -use crate::xsd::primitives::Numeric; -use crate::xsd::primitives::Primitive; -use std::collections::HashMap; -use std::fs::OpenOptions; -use std::io::Write; -use std::ops::Deref; - -pub fn write_tabs(w: &mut W, num: u32) -> std::io::Result<()> { - for _ in 0..num { - write!(w, " ")?; - } - Ok(()) -} - -macro_rules! w { - ($w:expr, $tabs:expr, $($arg:expr),+) => {{ - crate::generate::cpp::write_numerics::write_tabs($w, $tabs)?; - write!($w, $($arg),+) - }}; -} - -macro_rules! l { - ($w:expr, $tabs:expr, $($arg:expr),+) => {{ - crate::generate::cpp::write_numerics::write_tabs($w, $tabs)?; - writeln!($w, $($arg),+) - }}; -} - -impl Writer { - pub(crate) fn write_integers(&self, mut numerics: Vec>) -> Result<()> { - // yuckily add these because i'm not dealing with XSD built-ins right now, but I used - // PositiveInteger is referenced by, e.g. PositiveIntegerOrEmpty - let positive_integer = NumericData { - name: Symbol::new("positiveInteger"), - base_type: Numeric::PositiveInteger, - documentation: String::from("The built-in primitive xs:positiveInteger"), - range: Range { - min: Some(Bound::Inclusive(1 as i64)), - max: None, - }, - }; - let non_negative_integer = NumericData { - name: Symbol::new("nonNegativeInteger"), - base_type: Numeric::NonNegativeInteger, - documentation: String::from("The built-in primitive xs:nonNegativeInteger"), - range: Range { - min: Some(Bound::Inclusive(0 as i64)), - max: None, - }, - }; - // i used an 'int range' for Color to clamp the range of the bytes from 0-255. to replace - // that i'll create a 'Byte' numeric - let byte = NumericData { - name: Symbol::new("byte"), - base_type: Numeric::NonNegativeInteger, - documentation: String::from( - "This is not part of MusicXML. It represents a clamped byte.", - ), - range: Range { - min: Some(Bound::Inclusive(0 as i64)), - max: Some(Bound::Inclusive(255 as i64)), - }, - }; - numerics.push(byte); - numerics.push(positive_integer); - numerics.push(non_negative_integer); - numerics.sort_by(|a, b| { - let a = a.name.pascal(); - let b = b.name.pascal(); - a.cmp(b) - }); - self.write_integers_h(numerics.as_slice())?; - self.write_integers_cpp(&numerics)?; - Ok(()) - } - - fn write_integers_h(&self, numerics: &[NumericData]) -> Result<()> { - let mut contents = String::new(); - let mut nothing = HashMap::::new(); - - let builtins = render(INTEGER_BUILTINS_H, ¬hing)?; - contents.push_str(&builtins); - for numeric in numerics { - let mut data = HashMap::new(); - data.insert("classname", numeric.name.pascal().to_owned()); - data.insert("documentation", documentation(document_int(numeric), 2)?); - let rendered_type = render(INTEGER_TYPE_H, &data)?; - contents.push('\n'); - contents.push('\n'); - contents.push_str(&rendered_type); - } - let file_contents = - render_core_h(contents, None, Some(&mut ["iostream", "string", "limits"]))?; - wrap!(std::fs::write(&self.paths.integers_h, file_contents))?; - Ok(()) - } - - fn write_integers_cpp(&self, numerics: &[NumericData]) -> Result<()> { - let mut contents = render(INTEGER_BUILTINS_CPP, NO_DATA.deref())?; - for (i, numeric) in numerics.iter().enumerate() { - let (min, max) = min_max_ints(numeric); - let classname = numeric.name.pascal(); - let mut data = HashMap::new(); - data.insert("min_val", min); - data.insert("max_val", max); - data.insert("classname", classname.to_owned()); - let mut rendered = String::from("\n\n"); - rendered.push_str(render(INTEGER_TYPE_CPP, &data)?.as_str()); - if i < numerics.len() - 1 {} - contents.push_str(&rendered); - } - let file_contents = render_core_cpp( - contents, - Some("mx/core/Integers.h"), - None, - Some(&mut ["sstream"]), - )?; - wrap!(std::fs::write(&self.paths.integers_cpp, file_contents))?; - Ok(()) - } - - //////////////////////////////////////////////////////////////////////////////////////////////// - pub(crate) fn write_decimals(&self, mut numerics: Vec>) -> Result<()> { - // TODO - this needs to be properly generated - let positive_divisions_value = NumericData { - name: Symbol::new("positive-divisions-value"), - base_type: Numeric::Decimal, - documentation: String::from("TODO - this needs to be properly generated"), - range: Range { - min: Some(Bound::Exclusive(0 as f64)), - max: None, - }, - }; - numerics.push(positive_divisions_value); - numerics.sort_by(|a, b| { - let a = a.name.pascal(); - let b = b.name.pascal(); - a.cmp(b) - }); - self.write_decimals_h(&numerics)?; - self.write_decimals_cpp(&numerics)?; - Ok(()) - } - - fn write_decimals_h(&self, numerics: &[NumericData]) -> Result<()> { - let mut contents = String::new(); - let mut nothing = HashMap::::new(); - - let builtins = render(DECIMAL_BUILTINS_H, ¬hing)?; - contents.push_str(&builtins); - for numeric in numerics { - let mut data = HashMap::new(); - data.insert("classname", numeric.name.pascal().to_owned()); - data.insert( - "documentation", - documentation(document_decimal(numeric), 2)?, - ); - let rendered_type = render(DECIMAL_TYPE_H, &data)?; - contents.push('\n'); - contents.push('\n'); - contents.push_str(&rendered_type); - } - let file_contents = render_core_h( - contents, - None, - Some(&mut ["iostream", "string", "functional"]), - )?; - wrap!(std::fs::write(&self.paths.decimals_h, file_contents))?; - Ok(()) - } - - fn write_decimals_cpp(&self, numerics: &[NumericData]) -> Result<()> { - let mut contents = render(DECIMAL_BUILTINS_CPP, NO_DATA.deref())?; - for (i, numeric) in numerics.iter().enumerate() { - let (minexpr, maxexpr) = minmax_expr_decimal(numeric); - let defaultval = defaultval(numeric); - let classname = numeric.name.pascal(); - let mut data = HashMap::new(); - data.insert("classname", classname.to_owned()); - data.insert("minexpr", minexpr); - data.insert("maxexpr", maxexpr); - data.insert("defaultval", defaultval); - let mut rendered = String::from("\n\n"); - rendered.push_str(render(DECIMAL_TYPE_CPP, &data)?.as_str()); - if i < numerics.len() - 1 {} - contents.push_str(&rendered); - } - let file_contents = render_core_cpp( - contents, - Some("mx/core/Decimals.h"), - Some(&mut ["mx/core/UnusedParameter.h"]), - Some(&mut ["sstream", "cmath"]), - )?; - wrap!(std::fs::write(&self.paths.decimals_cpp, file_contents))?; - Ok(()) - } -} - -fn min_max_ints(numeric: &NumericData) -> (String, String) { - let (min, max) = maybe_min_max_ints(numeric); - ( - min.unwrap_or_else(|| String::from("IntMin")), - max.unwrap_or_else(|| String::from("IntMax")), - ) -} - -fn maybe_min_max_ints(numeric: &NumericData) -> (Option, Option) { - let min = numeric.range.min.as_ref().and_then(|bound| match bound { - Bound::Inclusive(i) => Some(format!("{}", *i)), - Bound::Exclusive(e) => Some(format!("{}", *e + 1)), - }); - let max = numeric.range.max.as_ref().and_then(|bound| match bound { - Bound::Inclusive(i) => Some(format!("{}", *i)), - Bound::Exclusive(e) => Some(format!("{}", *e - 1)), - }); - (min, max) -} - -fn describe_range_int(numeric: &NumericData) -> String { - let (min, max) = maybe_min_max_ints(numeric); - format!( - "Range: min={}, max={}", - min.unwrap_or_else(|| String::from("None")), - max.unwrap_or_else(|| String::from("None")) - ) -} - -fn describe_range_decimal(minmax: (String, String)) -> String { - // let (min, max) = maybe_min_max_ints(numeric); - format!("Range: min={}, max={}", minmax.0, minmax.1) -} - -fn minmax_expr_decimal(numeric: &NumericData) -> (String, String) { - let min = match numeric.range.min.as_ref() { - None => String::from("MX_NOOP"), - Some(bound) => match bound { - Bound::Inclusive(f) => format!("MXMININ( {} )", f), - Bound::Exclusive(f) => format!("MXMINEX( {} )", f), - }, - }; - let max = match numeric.range.max.as_ref() { - None => String::from("MX_NOOP"), - Some(bound) => match bound { - Bound::Inclusive(f) => format!("MXMAXIN( {} )", f), - Bound::Exclusive(f) => format!("MXMAXEX( {} )", f), - }, - }; - (min, max) -} - -fn defaultval(numeric: &NumericData) -> String { - match numeric.range.min.as_ref() { - None => String::from("0.0"), - Some(bound) => match bound { - Bound::Inclusive(f) => { - if *f > 0.0 { - format!("{}", f) - } else { - String::from("0.0") - } - } - Bound::Exclusive(f) => { - if *f >= 0.0 { - format!("{}", f + 1.0) - } else { - String::from("0.0") - } - } - }, - } -} - -fn document_int(numeric: &NumericData) -> String { - if numeric.documentation.is_empty() { - describe_range_int(numeric) - } else { - format!( - "{}\n\n{}", - numeric.documentation, - describe_range_int(numeric) - ) - } -} - -fn document_decimal(numeric: &NumericData) -> String { - let range = describe_range_decimal(decimal_range_doc_strings(numeric)); - if numeric.documentation.is_empty() { - range - } else { - format!("{}\n\n{}", numeric.documentation, range) - } -} - -fn decimal_range_doc_strings(numeric: &NumericData) -> (String, String) { - let min = match numeric.range.min.as_ref() { - None => String::from("None"), - Some(bound) => match bound { - Bound::Inclusive(f) => format!("Inclusive({})", f), - Bound::Exclusive(f) => format!("Exclusive({})", f), - }, - }; - let max = match numeric.range.max.as_ref() { - None => String::from("None"), - Some(bound) => match bound { - Bound::Inclusive(f) => format!("Inclusive({})", f), - Bound::Exclusive(f) => format!("Exclusive({})", f), - }, - }; - (min, max) -} diff --git a/gen/version-b/src/generate/cpp/write_unions.rs b/gen/version-b/src/generate/cpp/write_unions.rs deleted file mode 100644 index 5984f4bf0..000000000 --- a/gen/version-b/src/generate/cpp/write_unions.rs +++ /dev/null @@ -1,589 +0,0 @@ -use crate::error::{Error, Result}; -use crate::generate::cpp::cpp_template::{render_core_cpp, render_core_h}; -use crate::generate::cpp::helpers::{default_construct, enum_default}; -use crate::generate::cpp::writer::Writer; -use crate::generate::template::{ - render, CORE_H, DECIMAL_BUILTINS_CPP, DECIMAL_BUILTINS_H, DECIMAL_TYPE_CPP, DECIMAL_TYPE_H, - INTEGER_BUILTINS_CPP, INTEGER_BUILTINS_H, INTEGER_TYPE_CPP, INTEGER_TYPE_H, NO_DATA, - NUMBER_OR_NORMAL_CPP, NUMBER_OR_NORMAL_H, POSITIVE_INTEGER_OR_EMPTY_CPP, - POSITIVE_INTEGER_OR_EMPTY_H, UNION_CPP, UNION_H, -}; -use crate::model::scalar::{Bound, NumericData, Range, UnionData}; -use crate::model::scalar::{ScalarNumeric, ScalarString}; -use crate::model::symbol::Symbol; -use crate::model::{Def, Shape}; -use crate::utils::string_stuff::{documentation, sep, write_documentation}; -use crate::xsd::primitives::Numeric; -use crate::xsd::primitives::Primitive; -use crate::xsd::primitives::{BaseType, PrefixedString}; -use indexmap::set::IndexSet; -use indexmap::Equivalent; -use std::collections::HashMap; -use std::fs::{write, OpenOptions}; -use std::io::Write; -use std::ops::Deref; - -struct Info<'a> { - union: &'a UnionData, - named_members: &'a Vec<&'a Def>, - primitive_members: &'a HashMap, -} -impl<'a> Info<'a> { - fn find_def>(&'a self, name: S) -> Result<&'a Def> { - for &def in self.named_members { - if def.name().original() == name.as_ref() { - return Ok(def); - } - } - raise!("could not find '{}'", name.as_ref()) - } - - fn construction(&self, bt: &BaseType) -> Result { - // let first = self.union.members.first().ok_or_else(|| make_err!("no members"))?; - match bt { - BaseType::Custom(custom) => { - for &def in self.named_members { - return Ok(default_construct(def)); - } - return raise!("could not find def"); - } - _ => { - for (k, _) in self.primitive_members { - return Ok(format!("{}{{}}", k)); - } - return raise!("could not find the default primitive value"); - } - } - } - - fn construct_first(&self) -> Result { - let first = self - .union - .members - .first() - .ok_or_else(|| make_err!("no members"))?; - self.construction(first) - } - - fn h_includes(&self) -> Vec { - let mut map = HashMap::new(); - for &def in self.named_members { - match def { - Def::Enumeration(e) => { - let _ = map.insert("mx/core/Enums.h".to_owned(), ()); - } - Def::ScalarString(_) => { - let _ = map.insert("mx/core/Strings.h".to_owned(), ()); - } // TODO dumb? - Def::ScalarNumber(n) => match n { - ScalarNumeric::Decimal(_) => { - let _ = map.insert("mx/core/Decimals.h".to_owned(), ()); - } - ScalarNumeric::Integer(_) => { - let _ = map.insert("mx/core/Integers.h".to_owned(), ()); - } - }, - Def::CustomScalarString(s) => { - let _ = map.insert(format!("mx/core/{}.h", s.name.pascal()), ()); - } - Def::DerivedSimpleType(s) => { - let _ = map.insert(format!("mx/core/{}.h", s.name.pascal()), ()); - } - Def::UnionSimpleType(s) => { - let _ = map.insert(format!("mx/core/{}.h", s.name.pascal()), ()); - } - } - } - for (_, &include) in self.primitive_members { - map.insert(include.into(), ()); - } - let mut list = Vec::new(); - for (include, _) in &map { - list.push(include.to_owned()); - } - list.sort(); - list - } -} - -impl Writer { - pub(crate) fn write_unions(&self, mut unions: &[&UnionData]) -> Result<()> { - for &union in unions { - let mut data = HashMap::new(); - // find dependencies - let mut named_members = Vec::new(); - let mut primitive_members = HashMap::new(); - for member in &union.members { - match member { - BaseType::Custom(name) => { - let found = match self.model.get(Shape::Simple, name) { - None => { - return raise!( - "the dependency '{}' could not be found for union '{}'", - name, - union.name.original() - ) - } - Some(f) => f, - }; - named_members.push(found); - } - p => { - let primitive = p.primitive(); - let primitive_name = format!("{}", Symbol::new(format!("{}", p)).pascal()); - match primitive { - Primitive::None => panic!("can't happen"), - Primitive::Numeric => { - if member.is_decimal() { - primitive_members - .insert(primitive_name.clone(), "mx/core/Decimals.h"); - } else { - primitive_members - .insert(primitive_name.clone(), "mx/core/Integers.h"); - } - } - Primitive::Character => { - let _ = primitive_members - .insert(primitive_name.clone(), "mx/core/Strings.h"); - } - Primitive::DateType => { - let _ = primitive_members - .insert(primitive_name.clone(), "mx/core/Date.h"); - } - } - } - } - } - let info = Info { - union, - named_members: &named_members, - primitive_members: &primitive_members, - }; - data.insert("classname", union.name.pascal().into()); - data.insert("default_value", info.construct_first()?); - data.insert( - "documentation", - documentation(union.documentation.as_str(), 2)?, - ); - data.insert("parse_def", parse_def(&info)?); - data.insert("variants_ctor_decl", variants_ctor_decl(&info)?); - data.insert("variants_ctor_def", variants_ctor_def(&info)?); - data.insert("variants_get_decl", variants_get_decl(&info)?); - data.insert("variants_get_def", variants_get_def(&info)?); - data.insert("variants_get_is_decl", variants_get_is_decl(&info)?); - data.insert("variants_get_is_def", variants_get_is_def(&info)?); - data.insert("variants_set_decl", variants_set_decl(&info)?); - data.insert("variants_set_def", variants_set_def(&info)?); - data.insert("variants_template_decl", variants_template_decl(&info)); - data.insert("variants_to_stream_decl", variants_to_stream_decl(&info)); - - // These are funky - if union.name.original() == "positive-integer-or-empty" - || union.name.original() == "number-or-normal" - { - self.custom_unions(union, &mut data)?; - continue; - } - - let hpath = self.paths.core.join(format!("{}.h", union.name.pascal())); - let cpppath = self.paths.core.join(format!("{}.cpp", union.name.pascal())); - let hcontents = render(UNION_H, &data)?; - let cppcontents = render(UNION_CPP, &data)?; - let mut h_includes = info.h_includes(); - let mut h_strs: Vec<&str> = h_includes.iter().map(|s| s.as_str()).collect(); - let mut std_h = vec!["string", "variant", "ostream"]; - let h = render_core_h( - hcontents, - Some(h_strs.as_mut_slice()), - Some(std_h.as_mut_slice()), - )?; - let self_import = format!("mx/core/{}.h", union.name.pascal()); - let mut std_cpp = vec!["sstream", "type_traits"]; - let cpp = render_core_cpp( - cppcontents, - Some(self_import), - None, - Some(std_cpp.as_mut_slice()), - )?; - wrap!(write(hpath, h))?; - wrap!(write(cpppath, cpp))?; - } - Ok(()) - } - - pub(crate) fn write_unions_old(&self, mut unions: &[&UnionData]) -> Result<()> { - for &union in unions { - // we check each union to make sure its members match our expectations, - // then we copy the hand-written implementation. by checking the members - // we ensure that we don't miss a change in musicxml.xsd - match union.name.original() { - "font-size" => { - if union.members.len() != 2 { - return raise!("font-size has wrong number of members: {:?}", union); - } - if !union.members.get(0).unwrap().is_decimal() { - return raise!("font-size expected decimal"); - } - if union.members.get(1).unwrap().name() != "css-font-size" { - return raise!("font-size expected decimal"); - } - self.write_union(union)?; - } - unhanded => return raise!("unhandled union: '{}'", unhanded), - } - } - Ok(()) - } - - fn write_union(&self, union: &UnionData) -> Result<()> { - let mut data = HashMap::new(); - let members = union - .members - .iter() - .map(|item| format!("{}", item)) - .collect::>() - .join(", "); - data.insert("classname", union.name.pascal()); - data.insert("documentation", union.documentation.as_str()); - data.insert("union", &members); - let filename_h = format!("{}.h", union.name.pascal()); - let filename_cpp = format!("{}.cpp", union.name.pascal()); - let template_h = format!("{}.template", filename_h); - let template_cpp = format!("{}.template", filename_cpp); - let contents_h = render(template_h, &data)?; - wrap!(std::fs::write( - self.paths.core.join(&filename_h), - contents_h - )); - let contents_cpp = render(template_cpp, &data)?; - wrap!(std::fs::write( - self.paths.core.join(&filename_cpp), - contents_cpp - )); - Ok(()) - } - - fn custom_unions(&self, union: &UnionData, data: &mut HashMap<&str, String>) -> Result<()> { - let (hfilename, cppfilename, mut includes) = - if union.name.original() == "positive-integer-or-empty" { - ( - POSITIVE_INTEGER_OR_EMPTY_H, - POSITIVE_INTEGER_OR_EMPTY_CPP, - vec!["mx/core/Integers.h"], - ) - } else if union.name.original() == "number-or-normal" { - ( - NUMBER_OR_NORMAL_H, - NUMBER_OR_NORMAL_CPP, - vec!["mx/core/Decimals.h"], - ) - } else { - return raise!("unexpected type '{}'", union.name.original()); - }; - let hstuff = render(hfilename, data)?; - let cstuff = render(cppfilename, data)?; - let h = render_core_h( - hstuff, - Some(includes.as_mut_slice()), - Some(vec!["string", "memory", "iostream"].as_mut_slice()), - )?; - let self_include = format!("mx/core/{}.h", union.name.pascal()); - let mut c_include = vec!["sstream"]; - let c = render_core_cpp( - cstuff, - Some(&self_include), - None, - Some(c_include.as_mut_slice()), - )?; - wrap!(write( - self.paths.core.join(format!("{}.h", union.name.pascal())), - h - ))?; - wrap!(write( - self.paths.core.join(format!("{}.cpp", union.name.pascal())), - c - ))?; - Ok(()) - } -} - -fn parse_def(i: &Info<'_>) -> Result { - let mut s = String::new(); - for m in &i.union.members { - if let BaseType::Custom(name) = m { - let def = i.find_def(name)?; - if let Def::Enumeration(enumer) = def { - s.push_str( - format!( - " const auto {} = tryParse{}( value );\n", - enumer.name.camel(), - enumer.name.pascal() - ) - .as_str(), - ); - s.push_str(format!(" if( {} )\n", enumer.name.camel()).as_str()); - s.push_str(" {\n"); - s.push_str( - format!( - " set{}( *{} );\n", - enumer.name.pascal(), - enumer.name.camel() - ) - .as_str(), - ); - s.push_str(" return true;\n"); - s.push_str(" }\n"); - continue; - } else { - let name = Symbol::new(format!("{}", m)); - s.push_str( - format!( - " auto {} = {}{{}};\n", - name.camel(), - name.pascal() - ) - .as_str(), - ); - s.push_str(format!(" if( {}.parse( value ) )\n", name.camel()).as_str()); - s.push_str(" {\n"); - s.push_str( - format!( - " set{}( {} );\n", - name.pascal(), - name.camel() - ) - .as_str(), - ); - s.push_str(" return true;\n"); - s.push_str(" }\n"); - } - } else { - let name = Symbol::new(format!("{}", m)); - s.push_str( - format!( - " auto {} = {}{{}};\n", - name.camel(), - name.pascal() - ) - .as_str(), - ); - s.push_str(format!(" if( {}.parse( value ) )\n", name.camel()).as_str()); - s.push_str(" {\n"); - s.push_str( - format!( - " set{}( {} );\n", - name.pascal(), - name.camel() - ) - .as_str(), - ); - s.push_str(" return true;\n"); - s.push_str(" }\n"); - } - } - s.push_str(" return false;"); - Ok(s) -} - -fn variants_ctor_decl(i: &Info<'_>) -> Result { - let mut s = String::new(); - let clss = i.union.name.pascal(); - for (j, m) in i.union.members.iter().enumerate() { - s.push_str( - format!( - " explicit {}( {} value );", - clss, - m.to_symbol().pascal() - ) - .as_str(), - ); - if j < i.union.members.len() - 1 { - s.push('\n'); - } - } - Ok(s) -} -fn variants_ctor_def(i: &Info<'_>) -> Result { - let mut s = String::new(); - let clss = i.union.name.pascal(); - for (j, m) in i.union.members.iter().enumerate() { - s.push_str( - format!( - " {}::{}( {} value )\n", - clss, - clss, - m.to_symbol().pascal() - ) - .as_str(), - ); - let do_move = match i.find_def(m.name()) { - Ok(ok) => match ok { - Def::Enumeration(_) => false, - _ => true, - }, - Err(_) => true, - }; - if do_move { - s.push_str(" : myValue{ std::move( value ) }\n"); - } else { - s.push_str(" : myValue{ value }\n"); - } - s.push_str(" {\n"); - s.push_str("\n"); - s.push_str(" }\n"); - if j < i.union.members.len() - 1 { - s.push('\n'); - } - } - Ok(s) -} -fn variants_get_decl(i: &Info<'_>) -> Result { - let mut s = String::new(); - let clss = i.union.name.pascal(); - for (j, m) in i.union.members.iter().enumerate() { - let symbol = m.to_symbol(); - let pascal = symbol.pascal(); - s.push_str(format!(" {} getValue{}() const;", pascal, pascal).as_str()); - if j < i.union.members.len() - 1 { - s.push('\n'); - } - } - Ok(s) -} - -fn variants_get_def(i: &Info<'_>) -> Result { - let mut s = String::new(); - let clss = i.union.name.pascal(); - for (j, m) in i.union.members.iter().enumerate() { - let symbol = m.to_symbol(); - let pascal = symbol.pascal(); - s.push_str(format!(" {} {}::getValue{}() const\n", pascal, clss, pascal).as_str()); - s.push_str(" {\n"); - s.push_str(format!(" auto result = {};\n", i.construction(m)?).as_str()); - s.push_str(" std::visit([&](auto&& arg)\n"); - s.push_str(" {\n"); - s.push_str(" using T = std::decay_t;\n"); - for (k, inner) in i.union.members.iter().enumerate() { - let inner_symbol = inner.to_symbol(); - let inner_pascal = inner_symbol.pascal(); - let equals = if inner.name() == m.name() { - String::from("arg") - } else { - i.construction(m)? - }; - let else_str = if k == 0 { "" } else { "else " }; - s.push_str( - format!( - " {}if constexpr( std::is_same_v )\n", - else_str, inner_pascal - ) - .as_str(), - ); - s.push_str(format!(" result = {};\n", equals).as_str()); - } - s.push_str(" else\n"); - s.push_str( - " static_assert(always_false_v, \"non-exhaustive visitor!\");\n", - ); - s.push_str(" }, myValue);\n"); - s.push_str(" return result;\n"); - s.push_str(" }"); - if j < i.union.members.len() - 1 { - s.push_str("\n\n"); - } - } - Ok(s) -} - -fn variants_get_is_decl(i: &Info<'_>) -> Result { - let mut s = String::new(); - let clss = i.union.name.pascal(); - for (j, m) in i.union.members.iter().enumerate() { - let symbol = m.to_symbol(); - let pascal = symbol.pascal(); - s.push_str(format!(" bool getIs{}() const;", pascal).as_str()); - if j < i.union.members.len() - 1 { - s.push('\n'); - } - } - Ok(s) -} -fn variants_get_is_def(i: &Info<'_>) -> Result { - let mut s = String::new(); - let clss = i.union.name.pascal(); - for (j, m) in i.union.members.iter().enumerate() { - let symbol = m.to_symbol(); - let pascal = symbol.pascal(); - s.push_str(format!(" bool {}::getIs{}() const\n", clss, pascal).as_str()); - s.push_str(" {\n"); - s.push_str(format!(" return myValue.index() == {};\n", j).as_str()); - s.push_str(" }\n"); - if j < i.union.members.len() - 1 { - s.push('\n'); - } - } - Ok(s) -} -fn variants_set_decl(i: &Info<'_>) -> Result { - let mut s = String::new(); - let clss = i.union.name.pascal(); - for (j, m) in i.union.members.iter().enumerate() { - let symbol = m.to_symbol(); - let pascal = symbol.pascal(); - s.push_str(format!(" void set{}( {} value );", pascal, pascal).as_str()); - if j < i.union.members.len() - 1 { - s.push('\n'); - } - } - Ok(s) -} -fn variants_set_def(i: &Info<'_>) -> Result { - let mut s = String::new(); - let clss = i.union.name.pascal(); - for (j, m) in i.union.members.iter().enumerate() { - let symbol = m.to_symbol(); - let pascal = symbol.pascal(); - s.push_str(format!(" void {}::set{}( {} value )\n", clss, pascal, pascal).as_str()); - s.push_str(" {\n"); - s.push_str(format!(" myValue.emplace<{}>( value );\n", pascal).as_str()); - s.push_str(" }\n"); - if j < i.union.members.len() - 1 { - s.push('\n'); - } - } - Ok(s) -} - -fn variants_template_decl(i: &Info<'_>) -> String { - let names: Vec = i - .union - .members - .iter() - .map(|m| m.to_symbol()) - .map(|s| s.pascal().to_owned()) - .collect(); - names.join(", ") -} - -fn variants_to_stream_decl(i: &Info<'_>) -> String { - let mut s = String::new(); - let clss = i.union.name.pascal(); - for (j, m) in i.union.members.iter().enumerate() { - let symbol = m.to_symbol(); - let pascal = symbol.pascal(); - s.push_str(format!(" if( value.getIs{}() )\n", pascal).as_str()); - s.push_str(" {\n"); - s.push_str( - format!( - " toStream( os, value.getValue{}() );\n", - pascal - ) - .as_str(), - ); - s.push_str(" }"); - if j < i.union.members.len() - 1 { - s.push('\n'); - } - } - s -} diff --git a/gen/version-b/src/generate/cpp/writer.rs b/gen/version-b/src/generate/cpp/writer.rs deleted file mode 100644 index 1c01cde80..000000000 --- a/gen/version-b/src/generate/cpp/writer.rs +++ /dev/null @@ -1,65 +0,0 @@ -use crate::error::Result; -use crate::generate::cpp::write_custom::{ - write_color, write_comma_separated_text, write_ending_number, write_time_only, -}; -use crate::generate::paths::Paths; -use crate::model::scalar::ScalarNumeric; -use crate::model::{Def, Model}; - -#[derive(Debug, Clone)] -pub struct Writer { - pub model: Model, - pub paths: Paths, -} - -impl Writer { - pub fn new(model: Model) -> Self { - Self { - model, - paths: Paths::default(), - } - } - - pub fn write_code(&self) -> Result<()> { - let mut enums = Vec::new(); - let mut decimals = Vec::new(); - let mut integers = Vec::new(); - let mut unions = Vec::new(); - for model in self.model.defs() { - match model { - Def::Enumeration(e) => enums.push(e), - Def::ScalarString(s) => { - // We handle all of the scalar strings that we know of in musicxml.xsd with - // custom implementations, thus there is currently no 'generic' implementation. - return raise!( - "Encountered ScalarString '{}', no handler available.", - s.name.original() - ); - } - Def::CustomScalarString(cs) => match cs.name.original() { - "color" => write_color(cs, &self.paths)?, - "comma-separated-text" => write_comma_separated_text(cs, &self.paths)?, - "time-only" => write_time_only(cs, &self.paths)?, - "ending-number" => write_ending_number(cs, &self.paths)?, - unhandled => return raise!("Unhandled CustomScalarString '{}'", unhandled), - }, - Def::ScalarNumber(sn) => match sn { - ScalarNumeric::Decimal(d) => decimals.push(d.to_owned()), - ScalarNumeric::Integer(i) => integers.push(i.to_owned()), - }, - Def::DerivedSimpleType(derived_from) => { - return raise!( - "DerivedSimpleTypes not implemented: '{}'", - derived_from.name.original() - ) - } - Def::UnionSimpleType(u) => unions.push(u), - } - } - self.write_enums(&mut enums)?; - self.write_integers(integers)?; - self.write_decimals(decimals)?; - self.write_unions(unions.as_slice())?; - Ok(()) - } -} diff --git a/gen/version-b/src/generate/data/NumberOrNormal.cpp.template b/gen/version-b/src/generate/data/NumberOrNormal.cpp.template deleted file mode 100644 index 2e14e3fe8..000000000 --- a/gen/version-b/src/generate/data/NumberOrNormal.cpp.template +++ /dev/null @@ -1,144 +0,0 @@ - class NumberOrNormal::impl - { - public: - explicit impl() - :myDecimal( 0 ) - ,myIsNormal( true ) - {} - - explicit impl( const Decimal& value ) - :myDecimal( value ) - ,myIsNormal( false ) - {} - - explicit impl( const std::string& value ) - :myDecimal( 0 ) - ,myIsNormal( false ) - { - parse( value ); - } - - bool getIsNormal() const - { - return myIsNormal; - } - bool getIsNumber() const - { - return ! myIsNormal; - } - void setValueNormal() - { - myDecimal = Decimal( 0 ); - myIsNormal = true;; - } - void setValue( const Decimal& value ) - { - myDecimal = Decimal( value ); - myIsNormal = false; - } - Decimal getValueNumber() const - { - return myDecimal; - } - void parse( const std::string& value ) - { - if ( value == "normal" ) - { - myDecimal = Decimal( 0 ); - myIsNormal = true; - } - else - { - /* if it contains only numeric - characters it must be a number */ - myDecimal.parse( value ); - myIsNormal = false; - } - } - private: - Decimal myDecimal; - bool myIsNormal; - }; - - - NumberOrNormal::NumberOrNormal() - :myImpl( new impl() ) - {} - - NumberOrNormal::NumberOrNormal( const Decimal& value ) - :myImpl( new impl( value ) ) - {} - - NumberOrNormal::NumberOrNormal( const std::string& value ) - :myImpl( new impl( value ) ) - {} - - NumberOrNormal::~NumberOrNormal() {} - - NumberOrNormal::NumberOrNormal( const NumberOrNormal& other ) - :myImpl( new NumberOrNormal::impl( *other.myImpl ) ) - {} - - NumberOrNormal::NumberOrNormal( NumberOrNormal&& other ) - :myImpl( std::move( other.myImpl ) ) - {} - - NumberOrNormal& NumberOrNormal::operator=( NumberOrNormal&& other ) - { - myImpl = std::move( other.myImpl ); - return *this; - } - - NumberOrNormal& NumberOrNormal::operator=( const NumberOrNormal& other ) - { - this->myImpl = std::unique_ptr( new NumberOrNormal::impl( *other.myImpl ) ); - return *this; - } - bool NumberOrNormal::getIsNormal() const - { - return myImpl->getIsNormal(); - } - bool NumberOrNormal::getIsNumber() const - { - return myImpl->getIsNumber(); - } - void NumberOrNormal::setValueNormal() - { - myImpl->setValueNormal(); - } - void NumberOrNormal::setValue( const Decimal& value ) - { - myImpl->setValue( value ); - } - Decimal NumberOrNormal::getValueNumber() const - { - return myImpl->getValueNumber(); - } - - void NumberOrNormal::parse( const std::string& value ) - { - myImpl->parse( value ); - } - - std::string toString( const NumberOrNormal& value ) - { - std::stringstream ss; - toStream( ss, value ); - return ss.str(); - } - std::ostream& toStream( std::ostream& os, const NumberOrNormal& value ) - { - if ( value.getIsNumber() ) - { - toStream( os, value.getValueNumber() ); - } - else - { - os << "normal"; - } - return os; - } - std::ostream& operator<<( std::ostream& os, const NumberOrNormal& value ) - { - return toStream( os, value ); - } \ No newline at end of file diff --git a/gen/version-b/src/generate/data/NumberOrNormal.h.template b/gen/version-b/src/generate/data/NumberOrNormal.h.template deleted file mode 100644 index da9ad6a96..000000000 --- a/gen/version-b/src/generate/data/NumberOrNormal.h.template +++ /dev/null @@ -1,28 +0,0 @@ -{{ documentation }} - class NumberOrNormal - { - public: - explicit NumberOrNormal(); - explicit NumberOrNormal( const Decimal& value ); - explicit NumberOrNormal( const std::string& value ); - virtual ~NumberOrNormal(); - NumberOrNormal( const NumberOrNormal& other ); - NumberOrNormal( NumberOrNormal&& other ); - NumberOrNormal& operator=( const NumberOrNormal& other ); - NumberOrNormal& operator=( NumberOrNormal&& other ); - - bool getIsNormal() const; - bool getIsNumber() const; - void setValueNormal(); - void setValue( const Decimal& value ); - Decimal getValueNumber() const; - void parse( const std::string& value ); - - private: - class impl; - std::unique_ptr myImpl; - }; - - std::string toString( const NumberOrNormal& value ); - std::ostream& toStream( std::ostream& os, const NumberOrNormal& value ); - std::ostream& operator<<( std::ostream& os, const NumberOrNormal& value ); \ No newline at end of file diff --git a/gen/version-b/src/generate/data/PositiveIntegerOrEmpty.cpp.template b/gen/version-b/src/generate/data/PositiveIntegerOrEmpty.cpp.template deleted file mode 100644 index 8d372c790..000000000 --- a/gen/version-b/src/generate/data/PositiveIntegerOrEmpty.cpp.template +++ /dev/null @@ -1,147 +0,0 @@ - class PositiveIntegerOrEmpty::impl - { - public: - explicit impl() - :myPositiveInteger( 1 ) - ,myIsEmpty( true ) - {} - - explicit impl( const PositiveInteger& value ) - :myPositiveInteger( value ) - ,myIsEmpty( false ) - {} - - explicit impl( const std::string& value ) - :myPositiveInteger( 1 ) - ,myIsEmpty( false ) - { - parse( value ); - } - - bool getIsEmpty() const - { - return myIsEmpty; - } - bool getIsNumber() const - { - return ! myIsEmpty; - } - void setValueEmpty() - { - myPositiveInteger = PositiveInteger( 1 ); - myIsEmpty = true;; - } - void setValue( const PositiveInteger& value ) - { - myPositiveInteger = PositiveInteger( value ); - myIsEmpty = false; - } - PositiveInteger getValueNumber() const - { - return myPositiveInteger; - } - void parse( const std::string& value ) - { - if ( value == "" ) - { - myPositiveInteger = PositiveInteger( 1 ); - myIsEmpty = true; - } - else - { - /* if it contains only numeric - characters it must be a number */ - myPositiveInteger.parse( value ); - myIsEmpty = false; - } - } - private: - PositiveInteger myPositiveInteger; - bool myIsEmpty; - }; - - - PositiveIntegerOrEmpty::PositiveIntegerOrEmpty() - :myImpl( new impl() ) - {} - - PositiveIntegerOrEmpty::PositiveIntegerOrEmpty( const PositiveInteger& value ) - :myImpl( new impl( value ) ) - {} - - PositiveIntegerOrEmpty::PositiveIntegerOrEmpty( const std::string& value ) - :myImpl( new impl( value ) ) - {} - - PositiveIntegerOrEmpty::~PositiveIntegerOrEmpty() {} - - PositiveIntegerOrEmpty::PositiveIntegerOrEmpty( const PositiveIntegerOrEmpty& other ) - :myImpl( new PositiveIntegerOrEmpty::impl( *other.myImpl ) ) - {} - - PositiveIntegerOrEmpty::PositiveIntegerOrEmpty( PositiveIntegerOrEmpty&& other ) - :myImpl( std::move( other.myImpl ) ) - {} - - PositiveIntegerOrEmpty& PositiveIntegerOrEmpty::operator=( PositiveIntegerOrEmpty&& other ) - { - myImpl = std::move( other.myImpl ); - return *this; - } - - PositiveIntegerOrEmpty& PositiveIntegerOrEmpty::operator=( const PositiveIntegerOrEmpty& other ) - { - this->myImpl = std::unique_ptr( new PositiveIntegerOrEmpty::impl( *other.myImpl ) ); - return *this; - } - - bool PositiveIntegerOrEmpty::getIsEmpty() const - { - return myImpl->getIsEmpty(); - } - bool PositiveIntegerOrEmpty::getIsNumber() const - { - return myImpl->getIsNumber(); - } - void PositiveIntegerOrEmpty::setValueEmpty() - { - myImpl->setValueEmpty(); - } - void PositiveIntegerOrEmpty::setValue( const PositiveInteger& value ) - { - myImpl->setValue( value ); - } - PositiveInteger PositiveIntegerOrEmpty::getValueNumber() const - { - return myImpl->getValueNumber(); - } - - void PositiveIntegerOrEmpty::parse( const std::string& value ) - { - myImpl->parse( value ); - } - - std::string toString( const PositiveIntegerOrEmpty& value ) - { - std::stringstream ss; - toStream( ss, value ); - return ss.str(); - } - - std::ostream& toStream( std::ostream& os, const PositiveIntegerOrEmpty& value ) - { - if ( value.getIsNumber() ) - { - toStream( os, value.getValueNumber() ); - } - else - { - ; // os << ""; - } - return os; - } - - std::ostream& operator<<( std::ostream& os, const PositiveIntegerOrEmpty& value ) - { - return toStream( os, value ); - } \ No newline at end of file diff --git a/gen/version-b/src/generate/data/PositiveIntegerOrEmpty.h.template b/gen/version-b/src/generate/data/PositiveIntegerOrEmpty.h.template deleted file mode 100644 index a8a22447b..000000000 --- a/gen/version-b/src/generate/data/PositiveIntegerOrEmpty.h.template +++ /dev/null @@ -1,28 +0,0 @@ -{{ documentation }} - class PositiveIntegerOrEmpty - { - public: - explicit PositiveIntegerOrEmpty(); - explicit PositiveIntegerOrEmpty( const PositiveInteger& value ); - explicit PositiveIntegerOrEmpty( const std::string& value ); - virtual ~PositiveIntegerOrEmpty(); - PositiveIntegerOrEmpty( const PositiveIntegerOrEmpty& other ); - PositiveIntegerOrEmpty( PositiveIntegerOrEmpty&& other ); - PositiveIntegerOrEmpty& operator=( const PositiveIntegerOrEmpty& other ); - PositiveIntegerOrEmpty& operator=( PositiveIntegerOrEmpty&& other ); - - bool getIsEmpty() const; - bool getIsNumber() const; - void setValueEmpty(); - void setValue( const PositiveInteger& value ); - PositiveInteger getValueNumber() const; - void parse( const std::string& value ); - - private: - class impl; - std::unique_ptr myImpl; - }; - - std::string toString( const PositiveIntegerOrEmpty& value ); - std::ostream& toStream( std::ostream& os, const PositiveIntegerOrEmpty& value ); - std::ostream& operator<<( std::ostream& os, const PositiveIntegerOrEmpty& value ); \ No newline at end of file diff --git a/gen/version-b/src/generate/data/core.cpp.template b/gen/version-b/src/generate/data/core.cpp.template deleted file mode 100644 index 3ae648954..000000000 --- a/gen/version-b/src/generate/data/core.cpp.template +++ /dev/null @@ -1,11 +0,0 @@ -// MusicXML Class Library -// Copyright (c) by Matthew James Briggs -// Distributed under the MIT License{{ lead_whitespace }}{{ self_include }}{{ lib_includes }}{{ std_includes }} - -namespace mx -{ - namespace core - { -{{ contents }} - } -} diff --git a/gen/version-b/src/generate/data/core.h.template b/gen/version-b/src/generate/data/core.h.template deleted file mode 100644 index 23243f722..000000000 --- a/gen/version-b/src/generate/data/core.h.template +++ /dev/null @@ -1,13 +0,0 @@ -// MusicXML Class Library -// Copyright (c) by Matthew James Briggs -// Distributed under the MIT License - -#pragma once{{ lib_includes }}{{ std_includes }} - -namespace mx -{ - namespace core - { -{{ contents }} - } -} diff --git a/gen/version-b/src/generate/data/decimal_builtins.cpp.template b/gen/version-b/src/generate/data/decimal_builtins.cpp.template deleted file mode 100644 index bed231311..000000000 --- a/gen/version-b/src/generate/data/decimal_builtins.cpp.template +++ /dev/null @@ -1,399 +0,0 @@ - PreciseDecimal::PreciseDecimal( short inMaxIntegerDigits, short inMaxDecimalDigits, DecimalType inValue ) - : myIsNegative{ inValue < 0.0 } - , myInteger{ 0 } - , myDecimal{ 0 } - , myMaxIntegerDigits{ DEFAULT_MAX_INTEGER_DIGITS } - , myMaxDecimalDigits{ DEFAULT_MAX_DECIMAL_DIGITS } - { - setMaxIntegerDigits( inMaxIntegerDigits ); - setMaxDecimalDigits( inMaxDecimalDigits ); - setMaxExpressibleNumber(); - setValue( inValue ); - } - - PreciseDecimal::PreciseDecimal( short inMaxIntegerDigits, short inMaxDecimalDigits ) - : PreciseDecimal{ inMaxIntegerDigits, inMaxDecimalDigits, 0.0 } - { - - } - - PreciseDecimal::PreciseDecimal( DecimalType inValue ) - : PreciseDecimal{ DEFAULT_MAX_INTEGER_DIGITS, DEFAULT_MAX_DECIMAL_DIGITS, inValue } - { - - } - - PreciseDecimal::PreciseDecimal() - : PreciseDecimal{ DEFAULT_MAX_INTEGER_DIGITS, DEFAULT_MAX_DECIMAL_DIGITS, 0.0 } - { - - } - - DecimalType PreciseDecimal::getValue() const - { - return express( myInteger, myDecimal, myMaxDecimalDigits, myIsNegative ); - } - - static constexpr const long double POINT_FIVE = 0.4999999; - - void PreciseDecimal::setValue( DecimalType inValue ) - { - if ( inValue < 0 ) - { - myIsNegative = true; - inValue *= -1; - } - else - { - myIsNegative = false; - } - - const auto integer = static_cast( inValue ); - const bool isTooBig = integer > myMaxExpressibleInteger; - - if( isTooBig ) - { - myInteger = myMaxExpressibleInteger; - myDecimal = myMaxExpressibleDecimal; - return; - } - - const DecimalType decimalPartAsFloat = inValue - static_cast( integer ); - const auto powerMultiplierAsFloat = std::pow( static_cast( 10 ), static_cast( getMaxDecimalDigits() ) ); - const auto powerMultiplier = static_cast( std::ceil( powerMultiplierAsFloat - POINT_FIVE ) ); - const auto decimalDigitsShifted = decimalPartAsFloat * static_cast( powerMultiplier ); - const auto decimalDigits = static_cast( std::ceil( decimalDigitsShifted - POINT_FIVE ) ); - - if( decimalDigits > myMaxExpressibleDecimal ) - { - myInteger = integer + 1; - myDecimal = 0; - return; - } - - myInteger = integer; - myDecimal = decimalDigits; - } - - short PreciseDecimal::getMaxIntegerDigits() const - { - return myMaxIntegerDigits; - } - - short PreciseDecimal::getMaxDecimalDigits() const - { - return myMaxDecimalDigits; - } - - DecimalType PreciseDecimal::getMaxExpressibleNumber() const - { - return express( myMaxExpressibleInteger, myMaxExpressibleDecimal, myMaxDecimalDigits, myIsNegative ); - } - - DecimalType PreciseDecimal::getMinExpressibleNumber() const - { - return -1 * getMaxExpressibleNumber(); - } - - std::ostream& PreciseDecimal::toStream( std::ostream& os ) const - { - if( myInteger == 0 && myDecimal == 0 ) - { - os << "0"; - return os; - } - - if( myIsNegative ) - { - os << "-"; - } - - os << myInteger; - - if( myDecimal == 0 ) - { - return os; - } - - os << "."; - - auto decIntStr = std::to_string( myDecimal ); - std::stringstream ss; - - bool isNonZeroReached = false; - - for ( auto c = decIntStr.crbegin(); - c != decIntStr.crend(); - ++c ) - { - if( *c == '0' && !isNonZeroReached ) - { - continue; - } - - isNonZeroReached = true; - ss << *c; - } - - const auto backwards = ss.str(); - - short digits = 0; - decltype( myDecimal ) tens = 1; - - for( int i = 0; i <= myMaxDecimalDigits; ++i ) - { - ++digits; - tens *= 10; - const auto r = myDecimal / tens; - - if( r < 1 ) - { - break; - } - } - - short leadingZeros = myMaxDecimalDigits - digits; - - for ( short i = 0; i < leadingZeros; ++i ) - { - os << "0"; - } - - for ( auto c = backwards.crbegin(); - c != backwards.crend(); - ++c ) - { - os << *c; - } - - return os; - } - - std::string PreciseDecimal::toString() const - { - std::stringstream ss; - toStream( ss ); - return ss.str(); - } - - void PreciseDecimal::setMaxIntegerDigits( short inNumDigits ) - { - if( inNumDigits < 1 ) - { - myMaxIntegerDigits = 1; - return; - } - - if( inNumDigits > MAX_STORAGE_TYPE_DIGITS ) - { - myMaxIntegerDigits = MAX_STORAGE_TYPE_DIGITS; - return; - } - - myMaxIntegerDigits = inNumDigits; - } - - void PreciseDecimal::setMaxDecimalDigits( short inNumDigits ) - { - if( inNumDigits < 1 ) - { - myMaxDecimalDigits = 1; - return; - } - - if( inNumDigits > MAX_STORAGE_TYPE_DIGITS ) - { - myMaxDecimalDigits = MAX_STORAGE_TYPE_DIGITS; - return; - } - - myMaxDecimalDigits = inNumDigits; - } - - decltype( PreciseDecimal::myInteger ) PreciseDecimal::findMax( short inNumDigits ) - { - decltype( myInteger ) mult = 0; - decltype( myInteger ) result = 0; - - for( short i = 0; i < inNumDigits; ++i ) - { - mult = static_cast( std::ceil( std::pow( 10, i ) - 0.5) ); - const auto add = mult * 9; - result += add; - } - - return result; - } - - void PreciseDecimal::setMaxExpressibleInteger() - { - myMaxExpressibleInteger = findMax( getMaxIntegerDigits() ); - } - - void PreciseDecimal::setMaxExpressibleDecimal() - { - myMaxExpressibleDecimal = findMax( getMaxDecimalDigits() ); - } - - void PreciseDecimal::setMaxExpressibleNumber() - { - setMaxExpressibleInteger(); - setMaxExpressibleDecimal(); - } - - DecimalType PreciseDecimal::express( uint64_t inInteger, uint64_t inDecimal, short inMaxDecimalDigits, bool inIsNegative ) - { - const auto integer = static_cast( inInteger ); - const auto decimalPartAsFloat = static_cast( inDecimal ); - const auto powerMultiplierAsFloat = std::pow( static_cast( 10 ), static_cast( inMaxDecimalDigits ) ); - const auto powerMultiplier = static_cast( std::ceil( powerMultiplierAsFloat - 0.5 ) ); - const auto decimal = decimalPartAsFloat / powerMultiplier; - auto result = integer + decimal; - - if( inIsNegative ) - { - result *= -1; - } - - return result; - } - - Decimal::Decimal( DecimalType value ) - : myValue{ 19, DEFAULT_PRECISION, value } - { - - } - - Decimal::Decimal() - : Decimal{ 0.0 } - { - - } - - DecimalType Decimal::getValue() const - { - return myValue.getValue(); - } - - void Decimal::setValue( DecimalType value ) - { - myValue.setValue( value ); - } - - bool Decimal::parse( const std::string& value ) - { - std::stringstream ss( value ); - DecimalType temp = 0; - if ( ( ss >> temp ).fail() || !( ss >> std::ws ).eof()) - { - return false; - } - setValue( temp ); - return true; - } - - std::string Decimal::toString() const - { - return myValue.toString(); - } - - - std::ostream& Decimal::toStream( std::ostream& os ) const - { - return myValue.toStream( os ); - } - - - std::string toString( const Decimal& value, unsigned int precision ) - { - MX_UNUSED( precision ); - return value.toString(); - } - - - std::ostream& toStream( std::ostream& os, const Decimal& value, unsigned int precision ) - { - MX_UNUSED( precision ); - return value.toStream( os ); - } - - std::string toString( const Decimal& value, unsigned short precision ) - { - MX_UNUSED( precision ); - return value.toString(); - } - - std::ostream& toStream( std::ostream& os, const Decimal& value, unsigned short precision ) - { - MX_UNUSED( precision ); - return value.toStream( os ); - } - - std::ostream& operator<<( std::ostream& os, const Decimal& value ) - { - return value.toStream( os ); - } - - DecimalType minExclusive( DecimalType min, DecimalType val ) - { - if( val <= min ) - { - return min + NON_ZERO_AMOUNT; - } - - return val; - } - - DecimalType minInclusive( DecimalType min, DecimalType val ) - { - if( val < min ) - { - return min; - } - - return val; - } - - DecimalType maxExclusive( DecimalType max, DecimalType val ) - { - if( val >= max ) - { - return max - NON_ZERO_AMOUNT; - } - - return val; - } - - DecimalType maxInclusive( DecimalType max, DecimalType val ) - { - if( val > max ) - { - return max; - } - - return val; - } - - DecimalType noOp( DecimalType value ) - { - return value; - } - - DecimalRange::DecimalRange( DecimalClamp min, DecimalClamp max, DecimalType value ) - : Decimal{ min( max( value ) ) } - , myMinClamp{ min } - , myMaxClamp{ max } - { - - } - - void DecimalRange::setValue( DecimalType value ) - { - Decimal::setValue( myMinClamp( myMaxClamp( value ) ) ); - } - -#define MXMINEX( minbound ) DecimalClamp( []( DecimalType value ){ return minExclusive( minbound, value ); } ) -#define MXMAXEX( maxbound ) DecimalClamp( []( DecimalType value ){ return maxExclusive( maxbound, value ); } ) -#define MXMININ( minbound ) DecimalClamp( []( DecimalType value ){ return minInclusive( minbound, value ); } ) -#define MXMAXIN( maxbound ) DecimalClamp( []( DecimalType value ){ return maxInclusive( maxbound, value ); } ) -#define MX_NOOP DecimalClamp( noOp ) \ No newline at end of file diff --git a/gen/version-b/src/generate/data/decimal_builtins.h.template b/gen/version-b/src/generate/data/decimal_builtins.h.template deleted file mode 100644 index 6843021d8..000000000 --- a/gen/version-b/src/generate/data/decimal_builtins.h.template +++ /dev/null @@ -1,106 +0,0 @@ - /// The type we use for non-integral numbers in this library. - using DecimalType = long double; - constexpr const DecimalType DecimalMin = std::numeric_limits::min(); - constexpr const DecimalType DecimalMax = std::numeric_limits::max(); - - /// Decimals will be rounded to this number of places. - constexpr const unsigned short DEFAULT_PRECISION = 6; - - /// When a Decimal's range is Exclusive and you try to assign a number - /// that is out-of-range, this amount will be added to the exclusive - /// minimum. For example if a Decimal is constrained to be a positive - /// number, and you try to assign the value 0, the value will be set to - /// NON_ZERO_AMOUNT instead. - constexpr const DecimalType NON_ZERO_AMOUNT = 0.000001; - - using DecimalType = long double; - - /// @brief A precision representation of a decimal number - /// - /// @detailed Represents a decimal number with precision. Clamps - /// if an attempt is made to assign an unrepresentable number. - /// Rounds input values to the given MaxDecimalDigits or if a - /// change in precision would lead to data loss. Precision can - /// be changed at runtime. A number such as 123.4567 would require - /// a minimum precision setting of MaxIntegerDigits = 3, - /// MaxDecimalDigits = 4. - /// - class PreciseDecimal - { - public: - PreciseDecimal( short inMaxIntegerDigits, short inMaxDecimalDigits, DecimalType inValue ); - PreciseDecimal( short inMaxIntegerDigits, short inMaxDecimalDigits ); - PreciseDecimal( DecimalType inValue); - PreciseDecimal(); - DecimalType getValue() const; - void setValue( DecimalType inValue ); - short getMaxIntegerDigits() const; - short getMaxDecimalDigits() const; - DecimalType getMaxExpressibleNumber() const; - DecimalType getMinExpressibleNumber() const; - std::ostream& toStream( std::ostream& os ) const; - std::string toString() const; - - private: - bool myIsNegative; - uint64_t myInteger; - uint64_t myDecimal; - short myMaxIntegerDigits; - short myMaxDecimalDigits; - uint64_t myMaxExpressibleInteger; - uint64_t myMaxExpressibleDecimal; - - private: - void setMaxIntegerDigits( short inNumDigits ); - void setMaxDecimalDigits( short inNumDigits ); - static decltype( myInteger ) findMax( short inNumDigits ); - void setMaxExpressibleInteger(); - void setMaxExpressibleDecimal(); - void setMaxExpressibleNumber(); - static DecimalType express( uint64_t inInteger, uint64_t inDecimal, short inMaxDecimalDigits, bool inIsNegative ); - - private: - static constexpr const short DEFAULT_MAX_INTEGER_DIGITS = 10; - static constexpr const short DEFAULT_MAX_DECIMAL_DIGITS = 6; - static constexpr const short MAX_STORAGE_TYPE_DIGITS = 19; - static constexpr const uint64_t MAX_STORAGE_TYPE_VALUE = 9999999999999999999ULL; - }; - - class Decimal - { - public: - Decimal(); - explicit Decimal( DecimalType value ); - virtual ~Decimal() = default; - Decimal( const Decimal& ) = default; - Decimal( Decimal&& ) = default; - Decimal& operator=( const Decimal& ) = default; - Decimal& operator=( Decimal&& ) = default; - DecimalType getValue() const; - virtual void setValue( DecimalType value ); - bool parse( const std::string& value ); - std::string toString() const; - std::ostream& toStream( std::ostream& os ) const; - private: - PreciseDecimal myValue; - }; - - std::string toString( const Decimal& value, unsigned short precision = DEFAULT_PRECISION ); - std::ostream& toStream( std::ostream& os, const Decimal& value, unsigned short precision = DEFAULT_PRECISION ); - std::ostream& operator<<( std::ostream& os, const Decimal& value ); - - /// This type is an implementation detail. It represent a function that - /// clamps a DecimalType to a range. - using DecimalClamp = std::function; - - /// A 'clamped', or 'ranged' Decimal where the value of min and max are - /// governed by the DecimalClamp functions. - class DecimalRange : public Decimal - { - public: - explicit DecimalRange( DecimalClamp min, DecimalClamp max, DecimalType value ); - virtual void setValue( DecimalType value ); - private: - DecimalClamp myMinClamp; - DecimalClamp myMaxClamp; - }; \ No newline at end of file diff --git a/gen/version-b/src/generate/data/decimal_type.cpp.template b/gen/version-b/src/generate/data/decimal_type.cpp.template deleted file mode 100644 index da3128c33..000000000 --- a/gen/version-b/src/generate/data/decimal_type.cpp.template +++ /dev/null @@ -1,11 +0,0 @@ - {{ classname }}::{{ classname }}( DecimalType value ) - : DecimalRange{ {{ minexpr }}, {{ maxexpr }}, value } - { - - } - - {{ classname }}::{{ classname }}() - : {{ classname }}{ {{ defaultval }} } - { - - } \ No newline at end of file diff --git a/gen/version-b/src/generate/data/decimal_type.h.template b/gen/version-b/src/generate/data/decimal_type.h.template deleted file mode 100644 index e77a101d4..000000000 --- a/gen/version-b/src/generate/data/decimal_type.h.template +++ /dev/null @@ -1,7 +0,0 @@ -{{ documentation }} - class {{ classname }} : public DecimalRange - { - public: - explicit {{ classname }}( DecimalType value ); - {{ classname }}(); - }; \ No newline at end of file diff --git a/gen/version-b/src/generate/data/enum.cpp.template b/gen/version-b/src/generate/data/enum.cpp.template deleted file mode 100644 index e58c5ee27..000000000 --- a/gen/version-b/src/generate/data/enum.cpp.template +++ /dev/null @@ -1,29 +0,0 @@ - {{ banner }} - - {{ classname }} parse{{ classname }}( const std::string& value ) - { - const auto opt = tryParse{{ classname }}( value ); - return opt.value_or( {{ classname }}::{{ default_value_enum }} ); - } - - std::optional<{{ classname }}> tryParse{{ classname }}( const std::string& value ) - { -{{ enum_members_parse }} - return std::optional<{{ classname }}>{}; - } - - std::string toString( const {{ classname }} value ) - { -{{ enum_members_to_string }} - return "{{ to_string_default_return }}"; - } - - std::ostream& toStream( std::ostream& os, const {{ classname }} value ) - { - return os << toString( value ); - } - - std::ostream& operator<<( std::ostream& os, const {{ classname }} value ) - { - return toStream( os, value ); - } \ No newline at end of file diff --git a/gen/version-b/src/generate/data/enum.h.template b/gen/version-b/src/generate/data/enum.h.template deleted file mode 100644 index ea0ba5fa1..000000000 --- a/gen/version-b/src/generate/data/enum.h.template +++ /dev/null @@ -1,14 +0,0 @@ - {{ banner }} - /// -{{ documentation }} - /// - enum class {{ classname }} - { -{{ enum_members_declare }} - }; - - {{ classname }} parse{{ classname }}( const std::string& value ); - std::optional<{{ classname }}> tryParse{{ classname }}( const std::string& value ); - std::string toString( const {{ classname }} value ); - std::ostream& toStream( std::ostream& os, const {{ classname }} value ); - std::ostream& operator<<( std::ostream& os, const {{ classname }} value ); \ No newline at end of file diff --git a/gen/version-b/src/generate/data/enum_wrapper.cpp.template b/gen/version-b/src/generate/data/enum_wrapper.cpp.template deleted file mode 100644 index e5d2a65d6..000000000 --- a/gen/version-b/src/generate/data/enum_wrapper.cpp.template +++ /dev/null @@ -1,82 +0,0 @@ - {{ wrapper_classname }}::{{ wrapper_classname }}( const {{ classname }} value ) - : myEnum( value ) - , myCustomValue( "" ) - { - setValue( value ); - } - - {{ wrapper_classname }}::{{ wrapper_classname }}( const std::string& value ) - : myEnum( {{ classname }}::{{ other_field_name }} ) - , myCustomValue( value ) - { - setValue( value ); - } - - {{ wrapper_classname }}::{{ wrapper_classname }}() - : myEnum( {{ classname }}::{{ default_value_enum }} ) - , myCustomValue( "" ) - { - setValue( {{ classname }}::{{ default_value_enum }} ); - } - - {{ classname }} {{ wrapper_classname }}::getValue() const - { - return myEnum; - } - - std::string {{ wrapper_classname }}::getValueString() const - { - if ( myEnum != {{ classname }}::{{ other_field_name }} ) - { - return toString( myEnum ); - } - - else - { - return myCustomValue; - } - } - - void {{ wrapper_classname }}::setValue( const {{ classname }} value ) - { - myEnum = value; - if( value != {{ classname }}::{{ other_field_name }} && !myCustomValue.empty() ) - { - myCustomValue = ""; - } - } - - void {{ wrapper_classname }}::setValue( const std::string& value ) - { - const auto temp = tryParse{{ classname }}( value ); - if ( temp ) - { - myEnum = temp.value(); - myCustomValue = ""; - } - else - { - setValue( {{ classname }}::{{ other_field_name }} ); - myCustomValue = value; - } - } - - {{ wrapper_classname }} parse{{ wrapper_classname }}( const std::string& value ) - { - return {{ wrapper_classname }}( value ); - } - - std::string toString( const {{ wrapper_classname }}& value ) - { - return value.getValueString(); - } - - std::ostream& toStream( std::ostream& os, const {{ wrapper_classname }}& value ) - { - return os << toString( value ); - } - - std::ostream& operator<<( std::ostream& os, const {{ wrapper_classname }}& value ) - { - return toStream( os, value ); - } \ No newline at end of file diff --git a/gen/version-b/src/generate/data/enum_wrapper.h.template b/gen/version-b/src/generate/data/enum_wrapper.h.template deleted file mode 100644 index 0e99d4748..000000000 --- a/gen/version-b/src/generate/data/enum_wrapper.h.template +++ /dev/null @@ -1,19 +0,0 @@ - class {{ wrapper_classname }} - { - public: - explicit {{ wrapper_classname }}( const {{ classname }} value ); - explicit {{ wrapper_classname }}( const std::string& value ); - {{ wrapper_classname }}(); - {{ classname }} getValue() const; - std::string getValueString() const; - void setValue( const {{ classname }} value ); - void setValue( const std::string& value ); - private: - {{ classname }} myEnum; - std::string myCustomValue; - }; - - {{ wrapper_classname }} parse{{ wrapper_classname }}( const std::string& value ); - std::string toString( const {{ wrapper_classname }}& value ); - std::ostream& toStream( std::ostream& os, const {{ wrapper_classname }}& value ); - std::ostream& operator<<( std::ostream& os, const {{ wrapper_classname }}& value ); \ No newline at end of file diff --git a/gen/version-b/src/generate/data/integer_builtins.cpp.template b/gen/version-b/src/generate/data/integer_builtins.cpp.template deleted file mode 100644 index 233f6de7d..000000000 --- a/gen/version-b/src/generate/data/integer_builtins.cpp.template +++ /dev/null @@ -1,80 +0,0 @@ - Integer::Integer() - : Integer{ 0 } - { - - } - - Integer::Integer( IntType value ) - : myValue{ value } - { - - } - - IntType Integer::getValue() const - { - return myValue; - } - - void Integer::setValue( IntType value ) - { - myValue = value; - } - - bool Integer::parse( const std::string& value ) - { - std::stringstream ss( value ); - IntType temp = 0; - if ( ( ss >> temp ).fail() || !( ss >> std::ws ).eof()) - { - return false; - } - setValue( temp ); - return true; - } - - std::string toString( const Integer& value ) - { - std::stringstream ss; - toStream( ss, value ); - return ss.str(); - } - - std::ostream& toStream( std::ostream& os, const Integer& value ) - { - return os << value.getValue(); - } - - - std::ostream& operator<<( std::ostream& os, const Integer& value ) - { - return toStream( os, value ); - } - - inline IntType clamp( IntType min, IntType max, IntType value ) - { - if( value < min ) - { - return min; - } - else if( value > max ) - { - return max; - } - else - { - return value; - } - } - - IntRange::IntRange( IntType min, IntType max, IntType value ) - : Integer{ clamp( min, max, value ) } - , myMin{ min } - , myMax{ max } - { - - } - - void IntRange::setValue( IntType value ) - { - Integer::setValue( clamp( myMin, myMax, value ) ); - } \ No newline at end of file diff --git a/gen/version-b/src/generate/data/integer_builtins.h.template b/gen/version-b/src/generate/data/integer_builtins.h.template deleted file mode 100644 index 6f6a013a1..000000000 --- a/gen/version-b/src/generate/data/integer_builtins.h.template +++ /dev/null @@ -1,39 +0,0 @@ - /// Alias for the int type used by this library. - using IntType = int; - constexpr const IntType IntMin = std::numeric_limits::min(); - constexpr const IntType IntMax = std::numeric_limits::max(); - - /// A base class for all integer types. - class Integer - { - public: - Integer(); - explicit Integer( IntType value ); - virtual ~Integer() = default; - Integer( const Integer& ) = default; - Integer( Integer&& ) = default; - Integer& operator=( const Integer& ) = default; - Integer& operator=( Integer&& ) = default; - [[nodiscard]] IntType getValue() const; - virtual void setValue( IntType value ); - bool parse( const std::string& value ); - private: - IntType myValue; - }; - - - std::string toString( const Integer& value ); - std::ostream& toStream( std::ostream& os, const Integer& value ); - std::ostream& operator<<( std::ostream& os, const Integer& value ); - - /// A 'clamped', or 'ranged' Integer where the value can never be set - /// less than min or greater than max. - class IntRange : public Integer - { - public: - explicit IntRange( IntType min, IntType max, IntType value ); - void setValue( IntType value ) override; - private: - IntType myMin; - IntType myMax; - }; \ No newline at end of file diff --git a/gen/version-b/src/generate/data/integer_type.cpp.template b/gen/version-b/src/generate/data/integer_type.cpp.template deleted file mode 100644 index 3af75d468..000000000 --- a/gen/version-b/src/generate/data/integer_type.cpp.template +++ /dev/null @@ -1,11 +0,0 @@ - {{ classname }}::{{ classname }}() - :{{ classname }}{ 0 } - { - - } - - {{ classname }}::{{ classname }}( IntType value ) - :IntRange( {{ min_val }}, {{ max_val }}, value ) - { - - } \ No newline at end of file diff --git a/gen/version-b/src/generate/data/integer_type.h.template b/gen/version-b/src/generate/data/integer_type.h.template deleted file mode 100644 index 1fd9e415c..000000000 --- a/gen/version-b/src/generate/data/integer_type.h.template +++ /dev/null @@ -1,7 +0,0 @@ -{{ documentation }} - class {{ classname }} : public IntRange - { - public: - explicit {{ classname }}( IntType value ); - {{ classname }}(); - }; \ No newline at end of file diff --git a/gen/version-b/src/generate/data/union.cpp.template b/gen/version-b/src/generate/data/union.cpp.template deleted file mode 100644 index 833f29360..000000000 --- a/gen/version-b/src/generate/data/union.cpp.template +++ /dev/null @@ -1,41 +0,0 @@ - template inline constexpr bool always_false_v = false; - - {{ classname }}::{{ classname }}() - : myValue{ {{ default_value }} } - { - - } - -{{ variants_ctor_def }} - {{ classname }}::{{ classname }}( const std::string& value ) - : {{ classname }}{} - { - parse( value ); - } - -{{ variants_get_is_def }} -{{ variants_set_def }} -{{ variants_get_def }} - - bool {{ classname }}::parse( const std::string& value ) - { -{{ parse_def }} - } - - std::string toString( const {{ classname }}& value ) - { - std::stringstream ss; - toStream( ss, value ); - return ss.str(); - } - - std::ostream& toStream( std::ostream& os, const {{ classname }}& value ) - { -{{ variants_to_stream_decl }} - return os; - } - - std::ostream& operator<<( std::ostream& os, const {{ classname }}& value ) - { - return toStream( os, value ); - } \ No newline at end of file diff --git a/gen/version-b/src/generate/data/union.h.template b/gen/version-b/src/generate/data/union.h.template deleted file mode 100644 index 356c5218e..000000000 --- a/gen/version-b/src/generate/data/union.h.template +++ /dev/null @@ -1,19 +0,0 @@ -{{ documentation }} - class {{ classname }} - { - public: - explicit {{ classname }}(); -{{ variants_ctor_decl }} - explicit {{ classname }}( const std::string& value ); -{{ variants_get_is_decl }} -{{ variants_set_decl }} -{{ variants_get_decl }} - bool parse( const std::string& value ); - - private: - std::variant<{{ variants_template_decl }}> myValue; - }; - - std::string toString( const {{ classname }}& value ); - std::ostream& toStream( std::ostream& os, const {{ classname }}& value ); - std::ostream& operator<<( std::ostream& os, const {{ classname }}& value ); \ No newline at end of file diff --git a/gen/version-b/src/generate/mod.rs b/gen/version-b/src/generate/mod.rs deleted file mode 100644 index 4df223112..000000000 --- a/gen/version-b/src/generate/mod.rs +++ /dev/null @@ -1,45 +0,0 @@ -mod compile_mx; -pub mod cpp; -pub mod paths; -mod template; - -use crate::error::Result; -use crate::generate::cpp::modeler::MxModeler; -use crate::generate::paths::Paths; -use crate::model::create::Create; -use crate::model::creator::Creator; -use crate::model::post_process::PostProcess; -use crate::model::transform::Transform; -use crate::xsd::Xsd; -use cpp::constants::enum_member_substitutions; -use cpp::constants::{pseudo_enums, reserved_words, suffixed_enum_names}; -use std::fs::read_to_string; -use std::sync::Arc; - -#[derive(Clone, Debug)] -pub struct GenArgs { - pub paths: Paths, -} - -impl Default for GenArgs { - fn default() -> Self { - Self { - paths: Paths::default(), - } - } -} - -/// Generate `mx::core` in C++ -pub fn run(args: GenArgs) -> Result<()> { - let xsd = read_to_string(&args.paths.xsd_3_0).unwrap(); - let doc = exile::parse(xsd.as_str()).unwrap(); - let new_xsd = Xsd::load(&args.paths.xsd_3_0)?; - let transforms: Vec> = vec![Box::new(MxModeler::new())]; - let creates: Vec> = vec![Box::new(MxModeler::new())]; - let post_processors: Vec> = vec![Box::new(MxModeler::new())]; - let creator = Creator::new_with_default(Some(transforms), Some(creates), Some(post_processors)); - let models = creator.create(&new_xsd)?; - let cpp_writer = cpp::writer::Writer::new(models); - cpp_writer.write_code()?; - Ok(()) -} diff --git a/gen/version-b/src/generate/paths.rs b/gen/version-b/src/generate/paths.rs deleted file mode 100644 index 0c8160df9..000000000 --- a/gen/version-b/src/generate/paths.rs +++ /dev/null @@ -1,62 +0,0 @@ -use std::fs::{remove_file, File, OpenOptions}; -use std::path::{Path, PathBuf}; - -pub fn repo() -> PathBuf { - let mut p = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - p.pop(); - p.pop(); - p.canonicalize().unwrap() -} - -#[derive(Clone, Debug)] -pub struct Paths { - pub repo: PathBuf, - pub core: PathBuf, - pub enums_h: PathBuf, - pub enums_cpp: PathBuf, - pub integers_h: PathBuf, - pub integers_cpp: PathBuf, - pub decimals_h: PathBuf, - pub decimals_cpp: PathBuf, - pub xsd_3_0: PathBuf, - pub xsd_3_1: PathBuf, -} - -impl Default for Paths { - fn default() -> Self { - let r = repo(); - let core = r.join("src").join("private").join("mx").join("core"); - Self { - repo: r, - core: core.clone(), - enums_h: core.join("Enums.h"), - enums_cpp: core.join("Enums.cpp"), - integers_h: core.join("Integers.h"), - integers_cpp: core.join("Integers.cpp"), - decimals_h: core.join("Decimals.h"), - decimals_cpp: core.join("Decimals.cpp"), - xsd_3_0: repo().join("docs").join("musicxml.xsd"), - xsd_3_1: repo().join("docs").join("musicxml-3.1.xsd"), - } - } -} - -fn open_file>(p: P) -> File { - println!("opening a file for writing: '{}'", p.as_ref().display()); - OpenOptions::new() - .read(true) - .write(true) - .create(true) - .open(p) - .unwrap() // TODO - error? -} - -impl Paths { - pub fn create_core_file>(&self, filename: S) -> File { - let p = self.core.join(filename.as_ref()); - if p.is_file() { - remove_file(&p).unwrap(); - } - open_file(p) - } -} diff --git a/gen/version-b/src/generate/template.rs b/gen/version-b/src/generate/template.rs deleted file mode 100644 index bdf0c0640..000000000 --- a/gen/version-b/src/generate/template.rs +++ /dev/null @@ -1,129 +0,0 @@ -use crate::error::Result; -use handlebars::Handlebars; -use lazy_static::lazy_static; -use serde::Serialize; -use std::borrow::Borrow; -use std::collections::BTreeMap; -use std::collections::HashMap; -use std::fs; -use std::path::{Path, PathBuf}; - -pub const CORE_CPP: &str = "core.cpp.template"; -pub const CORE_H: &str = "core.h.template"; -pub const DECIMAL_BUILTINS_CPP: &str = "decimal_builtins.cpp.template"; -pub const DECIMAL_BUILTINS_H: &str = "decimal_builtins.h.template"; -pub const DECIMAL_TYPE_CPP: &str = "decimal_type.cpp.template"; -pub const DECIMAL_TYPE_H: &str = "decimal_type.h.template"; -pub const ENUM_CPP: &str = "enum.cpp.template"; -pub const ENUM_H: &str = "enum.h.template"; -pub const ENUM_WRAPPER_CPP: &str = "enum_wrapper.cpp.template"; -pub const ENUM_WRAPPER_H: &str = "enum_wrapper.h.template"; -pub const INTEGER_BUILTINS_CPP: &str = "integer_builtins.cpp.template"; -pub const INTEGER_BUILTINS_H: &str = "integer_builtins.h.template"; -pub const INTEGER_TYPE_CPP: &str = "integer_type.cpp.template"; -pub const INTEGER_TYPE_H: &str = "integer_type.h.template"; -pub const NUMBER_OR_NORMAL_CPP: &str = "NumberOrNormal.cpp.template"; -pub const NUMBER_OR_NORMAL_H: &str = "NumberOrNormal.h.template"; -pub const POSITIVE_INTEGER_OR_EMPTY_CPP: &str = "PositiveIntegerOrEmpty.cpp.template"; -pub const POSITIVE_INTEGER_OR_EMPTY_H: &str = "PositiveIntegerOrEmpty.h.template"; -pub const UNION_CPP: &str = "union.cpp.template"; -pub const UNION_H: &str = "union.h.template"; - -lazy_static! { - static ref DIR: PathBuf = manifest_dir().join("src").join("generate").join("data"); -} - -lazy_static! { - static ref HANDLEBARS: Handlebars<'static> = { - let mut handlebars = Handlebars::new(); - let files = list_template_files().unwrap(); - for (name, path) in &files { - handlebars.register_template_string(name, read(path).unwrap()); - } - handlebars - }; -} - -lazy_static! { - pub(crate) static ref NO_DATA: HashMap = HashMap::new(); -} - -pub(crate) fn render(name: STR, data: &SERIALIZE) -> Result -where - STR: AsRef, - SERIALIZE: Serialize, -{ - let h = &HANDLEBARS; - let rendered = h - .render(name.as_ref(), data) - .map_err(|e| make_err!("unable to render template '{}': {}", name.as_ref(), e))?; - Ok(rendered - .replace("&", "&") - .replace("<", "<") - .replace(">", ">") - .replace(""", "\"")) -} - -fn template_dir() -> &'static Path { - &DIR -} - -fn manifest_dir() -> PathBuf { - let dir = env!("CARGO_MANIFEST_DIR"); - PathBuf::from(dir) -} - -fn template_path>(filename: S) -> PathBuf { - template_dir().join(filename.as_ref()) -} - -fn read>(p: P) -> Result { - let p = p.as_ref(); - if !p.is_file() { - return raise!("not a file: '{}'", p.display()); - } - Ok(std::fs::read_to_string(p) - .map_err(|e| make_err!("cannot read file '{}': {}", p.display(), e))?) -} - -fn list_template_files() -> Result> { - let dir = template_dir(); - let dir = dir - .clone() - .canonicalize() - .map_err(|e| make_err!("directory not found '{}': {}", dir.display(), e))?; - if !dir.is_dir() { - return raise!("not a directory: '{}'", dir.display())?; - } - let mut list = Vec::new(); - for entry in fs::read_dir(&dir) - .map_err(|e| make_err!("unable to read dir '{}': {}", dir.display(), e))? - { - let entry = entry - .map_err(|e| make_err!("unable to read entry in dir '{}': {}", dir.display(), e))?; - if !entry.path().is_file() { - continue; - } - let path = entry.path(); - let ext = if let Some(ext) = path.extension() { - if let Some(ext) = ext.to_str() { - ext - } else { - return raise!("not utf-8: '{}'", entry.path().display()); - } - } else { - continue; - }; - if ext != "template" { - continue; - } - let filename = path - .file_name() - .ok_or_else(|| make_err!("no filename: '{}'", entry.path().display()))?; - let filename = filename - .to_str() - .ok_or_else(|| make_err!("not utf-8: '{:?}'", filename))?; - list.push((filename.to_owned(), path)) - } - Ok(list) -} diff --git a/gen/version-b/src/lib.rs b/gen/version-b/src/lib.rs deleted file mode 100644 index aa4df6b60..000000000 --- a/gen/version-b/src/lib.rs +++ /dev/null @@ -1,14 +0,0 @@ -#![deny(non_camel_case_types)] -#![deny(non_snake_case)] -#![deny(non_snake_case)] -#![deny(non_upper_case_globals)] -#![allow(unused)] -#![deny(rust_2018_idioms)] -#![deny(missing_debug_implementations, missing_copy_implementations)] - -#[macro_use] -pub mod error; -pub mod generate; -pub mod model; -pub mod utils; -pub mod xsd; diff --git a/gen/version-b/src/model/builtin.rs b/gen/version-b/src/model/builtin.rs deleted file mode 100644 index ecf17ff72..000000000 --- a/gen/version-b/src/model/builtin.rs +++ /dev/null @@ -1,22 +0,0 @@ -#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd)] -pub enum Builtin { - String(BuiltinString), - Number(BuiltinNumber), -} - -#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd)] -pub enum BuiltinString { - String, - Token, - IDToken, -} - -#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd)] -pub enum BuiltinNumber { - Integer, - NonNegativeInteger, - PositiveInteger, - Decimal, - NonNegativeDecimal, - PositiveDecimal, -} diff --git a/gen/version-b/src/model/create.rs b/gen/version-b/src/model/create.rs deleted file mode 100644 index ef8b1d348..000000000 --- a/gen/version-b/src/model/create.rs +++ /dev/null @@ -1,91 +0,0 @@ -use crate::model::Def; -use crate::xsd::{Entry, Xsd}; -use std::fmt::{Display, Formatter}; - -/// # Create Trait -/// -/// An object that takes a top-level `Entry` from the XSD document, and converts it into one or more -/// `Model` objects. -/// -/// # Purpose -/// -/// This library will provide a default `Create` implementation, but the trait allows users to -/// customize the interpretation of their XSD. Any number of `Create` implementations can be used -/// during the processing of the XSD. Each `Create` object will be tried, in order, and the first -/// one that returns `Some` will end the chain of attempts. -/// -/// # Return -/// -/// If `None` is returned, it indicates that the `Create` object ignored the input, i.e. subsequent -/// `Create` objects should try to handle the input. If `Some` is returned, but the `Vec` is empty, -/// then it means the `Create` object handled the input, chose not to produce any models, and -/// subsequent `Create` objects should not try to handle the input. Finally, a non-empty `Vec` means -/// that one or models were produced, again indicating that subsequent `Create` objects should not -/// attempt to create models. -/// -/// # Error -/// -/// We define a simple error type instead of using generics. -/// -pub trait Create { - /// The name of this `Create` object (for debugging). - fn name(&self) -> &'static str; - - /// Creates models based on a top-level XSD entry. Returns `None` if the XSD entry cannot be - /// handled. - fn create(&self, entry: &Entry, xsd: &Xsd) -> CreateResult; -} - -pub type CreateResult = std::result::Result>, CreateError>; - -#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)] -pub struct CreateError { - pub message: String, -} - -impl Display for CreateError { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.message.as_str()) - } -} - -impl std::error::Error for CreateError { - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - None - } -} - -impl CreateError { - pub fn new>(message: S) -> Self { - Self { - message: message.as_ref().into(), - } - } -} - -/// This macro is used internally to create an `Err(crate::error::Error::Message)`. -macro_rules! make_create_err { - () => { - crate::model::create::CreateError{ - message: "".to_owned(), - } - }; - ($msg:expr) => { - crate::model::create::CreateError{ - message: $msg.into(), - } - }; - ($fmt:expr, $($arg:expr),+) => { - crate::model::create::CreateError{ - message: format!($fmt, $($arg),+), - } - }; -} - -macro_rules! some_create_err { - ($($x:tt)*) => { - { - Some(Err(make_create_err!($($x)*))) - } - } -} diff --git a/gen/version-b/src/model/creator.rs b/gen/version-b/src/model/creator.rs deleted file mode 100644 index 7a56c27e7..000000000 --- a/gen/version-b/src/model/creator.rs +++ /dev/null @@ -1,123 +0,0 @@ -use crate::error::Result; -use crate::model::create::{Create, CreateError}; -use crate::model::post_process::PostProcess; -use crate::model::transform::Transform; -use crate::model::{Def, DefaultCreate, Model}; -use crate::xsd::{Entry, Xsd}; -use std::borrow::Cow; -use std::fmt::{Debug, Formatter}; - -/// The 'Creator' takes a vector of `Create` objects, applies them to an `XSD` producing a model. -pub struct Creator { - transforms: Option>>, - creates: Vec>, - post_processors: Option>>, -} - -impl Default for Creator { - fn default() -> Self { - Self { - transforms: None, - creates: vec![Box::new(DefaultCreate::default())], - post_processors: None, - } - } -} - -impl Creator { - /// Create a new `Creator` object by passing in the transform and create objects. - pub fn new( - transforms: Option>>, - creates: Vec>, - post_processors: Option>>, - ) -> Self { - Self { - transforms, - creates, - post_processors, - } - } - - /// Create a new `Creator` object by passing in the tranform and create objects. This function - /// will append the default `Create` implementation as the last last `Create` object. - pub fn new_with_default( - transforms: Option>>, - mut creates: Option>>, - post_processors: Option>>, - ) -> Self { - let mut creates = if let Some(the_goods) = creates { - the_goods - } else { - Vec::new() - }; - creates.push(Box::new(DefaultCreate::default())); - Self { - transforms, - creates, - post_processors, - } - } -} - -impl Debug for Creator { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "Creator{{ creates: [")?; - for create in &self.creates { - write!(f, "{},", create.name())?; - } - write!(f, "] }}") - } -} - -impl Creator { - pub fn create(&self, xsd: &Xsd) -> Result { - let mut defs: Vec = Vec::new(); - for mut entry in xsd.entries() { - let mut entry = entry.clone(); - if let Some(transforms) = &self.transforms { - for transform in transforms { - entry = wrap!(transform.transform(&entry, xsd))?; - } - } - let mut is_handled = false; - for create in &self.creates { - if let Some(mut more_models) = wrap!(create.create(&entry, xsd))? { - is_handled = true; - if let Some(post_processors) = &self.post_processors { - let mut post_processed_models = Vec::new(); - for model in &more_models { - let mut model_being_processed = model.clone(); - for post_processor in post_processors { - model_being_processed = - wrap!(post_processor.process(&model_being_processed, xsd))?; - } - post_processed_models.push(model_being_processed); - } - more_models = post_processed_models; - } - defs.append(&mut more_models); - break; - } - } - if !is_handled { - return raise!( - "the entry {} was not handled by any Create objects", - entry.id() - ); - } - } - let mut model = Model::default(); - for def in defs { - model.add(def); - } - Ok(model) - } - - fn transform<'a>( - &'a self, - entry: &'a Entry, - xsd: &Xsd, - ) -> std::result::Result, CreateError> { - Ok(Cow::Borrowed(entry)) - } -} diff --git a/gen/version-b/src/model/default_create/enumeration.rs b/gen/version-b/src/model/default_create/enumeration.rs deleted file mode 100644 index f917dba99..000000000 --- a/gen/version-b/src/model/default_create/enumeration.rs +++ /dev/null @@ -1,54 +0,0 @@ -use crate::model::create::{CreateError, CreateResult}; -use crate::model::enumeration::Enumeration; -use crate::model::symbol::Symbol; -use crate::model::Def; -use crate::xsd::restriction::Facet; -use crate::xsd::simple_type::{Payload, SimpleType}; -use crate::xsd::{simple_type, Xsd}; - -pub(super) fn is_enumeration(st: &SimpleType) -> bool { - match &st.payload { - Payload::Restriction(r) => { - if r.facets.is_empty() { - return false; - } - for facet in &r.facets { - match facet { - Facet::Enumeration(_) => continue, - _ => return false, - } - } - return true; - } - _ => false, - } -} - -pub(super) fn model_enumeration(st: &SimpleType, xsd: &Xsd) -> CreateResult { - let restriction = if let simple_type::Payload::Restriction(r) = &st.payload { - r - } else { - return Err(CreateError::new("expected restriction")); - }; - let mut members = Vec::new(); - for facet in &restriction.facets { - let s = if let Facet::Enumeration(s) = facet { - s - } else { - return Err(CreateError::new("expected enumeration")); - }; - members.push(Symbol::new(s.as_str())); - } - let default = members - .first() - .ok_or_else(|| make_create_err!("no members!"))? - .clone(); - let enm = Enumeration { - name: Symbol::new(st.name.as_str()), - members, - documentation: st.documentation(), - default, - other_field: None, - }; - Ok(Some(vec![Def::Enumeration(enm)])) -} diff --git a/gen/version-b/src/model/default_create/mod.rs b/gen/version-b/src/model/default_create/mod.rs deleted file mode 100644 index d5ee07dbf..000000000 --- a/gen/version-b/src/model/default_create/mod.rs +++ /dev/null @@ -1,61 +0,0 @@ -mod enumeration; -mod scalar; - -#[macro_use] -use crate::model::create::{Create, CreateError, CreateResult}; - -use crate::model::default_create::enumeration::{is_enumeration, model_enumeration}; -use crate::model::default_create::scalar::{ - model_derived_simple_type, model_scalar_number, model_scalar_string, -}; -use crate::model::enumeration::Enumeration; -use crate::model::scalar::ScalarNumeric; -use crate::model::symbol::Symbol; -use crate::model::Def; -use crate::xsd::restriction::Facet; -use crate::xsd::simple_type::{Payload, SimpleType}; -use crate::xsd::{simple_type, Entry, Xsd}; -use std::borrow::Borrow; -use std::ops::Deref; - -#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd)] -pub struct DefaultCreate {} - -impl Default for DefaultCreate { - fn default() -> Self { - Self {} - } -} - -impl Create for DefaultCreate { - fn name(&self) -> &'static str { - "default" - } - - fn create(&self, entry: &Entry, xsd: &Xsd) -> CreateResult { - match entry { - Entry::Annotation(_) => Ok(Some(Vec::new())), // TODO - implement Annotation - Entry::AttributeGroup(_) => Ok(Some(Vec::new())), // TODO - implement AttributeGroup - Entry::ComplexType(_) => Ok(Some(Vec::new())), // TODO - implement ComplexType - Entry::Element(_) => Ok(Some(Vec::new())), // TODO - implement Element - Entry::Group(_) => Ok(Some(Vec::new())), // TODO - implement Group - Entry::Import(_) => Ok(Some(Vec::new())), // TODO - implement Import - Entry::SimpleType(st) => dispatch_simple_type(st, xsd), - } - } -} - -fn dispatch_simple_type(st: &SimpleType, xsd: &Xsd) -> CreateResult { - if is_enumeration(st) { - model_enumeration(st, xsd) - } else if let Some(result) = model_scalar_string(st, xsd) { - result - } else if let Some(result) = model_scalar_number(st, xsd) { - result - } else if let Some(result) = model_derived_simple_type(st, xsd) { - result - } else { - //Err(make_create_err!("Unhandled SimpleType: '{}'", st.name)) - Ok(Some(Vec::new())) // TODO - implement other simple types - } -} diff --git a/gen/version-b/src/model/default_create/scalar.rs b/gen/version-b/src/model/default_create/scalar.rs deleted file mode 100644 index 5177ee601..000000000 --- a/gen/version-b/src/model/default_create/scalar.rs +++ /dev/null @@ -1,652 +0,0 @@ -#[macro_use] -use crate::model::create::{CreateError, CreateResult}; -use crate::model::scalar::{ - Bound, DerivedSimpleTypeData, NumericData, Range, ScalarNumeric, ScalarString, UnionData, -}; -use crate::model::symbol::Symbol; -use crate::model::Def; -use crate::xsd::primitives::{BaseType, Character, Numeric, Primitive}; -use crate::xsd::restriction::{Facet, Number, Restriction}; -use crate::xsd::simple_type::{Payload, SimpleType}; -use crate::xsd::Xsd; - -pub(super) fn model_scalar_string(st: &SimpleType, _xsd: &Xsd) -> Option { - match &st.payload { - Payload::Restriction(r) => { - if r.facets.is_empty() { - return None; - } - if !r.base.is_character() { - return None; - } - let base_type = r.base.as_character().unwrap(); - let mut scalar_string = match base_type { - Character::Language | Character::Name | Character::NormalizedString => { - return some_create_err!("'{}' is not supported", base_type); - } - _ => ScalarString { - name: Symbol::new(st.name.as_str()), - base_type, - documentation: st.documentation(), - ..Default::default() - }, - }; - for facet in &r.facets { - match facet { - Facet::Enumeration(_) - | Facet::MaxExclusive(_) - | Facet::MaxInclusive(_) - | Facet::MinExclusive(_) - | Facet::MinInclusive(_) => { - return some_create_err!("unsupported facet '{:?}'", facet) - } - Facet::Length(l) => { - scalar_string.min_length = Some(*l); - scalar_string.max_length = Some(*l); - } - Facet::MaxLength(l) => scalar_string.max_length = Some(*l), - Facet::MinLength(l) => scalar_string.min_length = Some(*l), - Facet::Pattern(p) => scalar_string.pattern = Some(p.clone()), - } - } - return Some(Ok(Some(vec![Def::ScalarString(scalar_string)]))); - } - _ => return None, - } -} - -pub(super) fn model_scalar_number(st: &SimpleType, _xsd: &Xsd) -> Option { - match &st.payload { - Payload::Restriction(r) => { - if !r.base.is_numeric() { - return None; - } - let base_type = r.base.as_numeric().unwrap(); - return Some(produce_the_scalar_numeric(base_type, r, st, _xsd)); - } - _ => return None, - } -} - -pub(super) fn model_derived_simple_type(st: &SimpleType, _xsd: &Xsd) -> Option { - match &st.payload { - Payload::Restriction(r) => { - let base_type = if let BaseType::Custom(s) = &r.base { - s - } else { - // not a derived type - return None; - }; - return Some(Ok(Some(vec![Def::DerivedSimpleType( - DerivedSimpleTypeData { - name: Symbol::new(&st.name), - base_type: base_type.into(), - documentation: st.documentation(), - }, - )]))); - } - Payload::Union(u) => { - return Some(Ok(Some(vec![Def::UnionSimpleType(UnionData { - name: Symbol::new(&st.name), - members: u.members.clone(), - documentation: st.documentation(), - })]))); - } - payload => { - return Some(Err(make_create_err!( - "model_derived_simple_type: unhandled payload: {:?}", - payload - ))) - } - } -} - -fn produce_the_scalar_numeric( - base_type: Numeric, - r: &Restriction, - st: &SimpleType, - _xsd: &Xsd, -) -> CreateResult { - let mut scalar_numeric = match base_type { - Numeric::Byte | Numeric::UnsignedByte => { - return Err(make_create_err!( - "Unsupported numeric type: '{}'", - base_type - )) - } - Numeric::Decimal => ScalarNumeric::Decimal(NumericData { - name: Symbol::new(st.name.as_str()), - base_type, - documentation: st.documentation(), - range: parse_decimal_range(Range::default(), &r.facets)?, - }), - - Numeric::NegativeInteger => ScalarNumeric::Integer(NumericData { - name: Symbol::new(st.name.as_str()), - base_type, - documentation: st.documentation(), - range: parse_integer_range(Range::new(None, Some(Bound::Inclusive(-1))), &r.facets)?, - }), - Numeric::NonNegativeInteger => ScalarNumeric::Integer(NumericData { - name: Symbol::new(st.name.as_str()), - base_type, - documentation: st.documentation(), - range: parse_integer_range(Range::new(Some(Bound::Inclusive(0)), None), &r.facets)?, - }), - Numeric::NonPositiveInteger => ScalarNumeric::Integer(NumericData { - name: Symbol::new(st.name.as_str()), - base_type, - documentation: st.documentation(), - range: parse_integer_range(Range::new(None, Some(Bound::Inclusive(0))), &r.facets)?, - }), - Numeric::PositiveInteger => ScalarNumeric::Integer(NumericData { - name: Symbol::new(st.name.as_str()), - base_type, - documentation: st.documentation(), - range: parse_integer_range(Range::new(Some(Bound::Inclusive(1)), None), &r.facets)?, - }), - Numeric::Int - | Numeric::Integer - | Numeric::Long - | Numeric::Short - | Numeric::UnsignedLong - | Numeric::UnsignedInt - | Numeric::UnsignedShort => ScalarNumeric::Integer(NumericData { - name: Symbol::new(st.name.as_str()), - base_type, - documentation: st.documentation(), - range: parse_integer_range(Range::default(), &r.facets)?, - }), - }; - Ok(Some(vec![Def::ScalarNumber(scalar_numeric)])) -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Wow what an incredible mess - -fn parse_decimal_range( - starting_range: Range, - facets: &[Facet], -) -> std::result::Result, CreateError> { - let mut min = starting_range.min.and_then(|some| match some { - Bound::Inclusive(i) => Some(LowerFloatBound::Inclusive(i)), - Bound::Exclusive(e) => Some(LowerFloatBound::Exclusive(e)), - }); - let mut max = starting_range.max.and_then(|some| match some { - Bound::Inclusive(i) => Some(UpperFloatBound::Inclusive(i)), - Bound::Exclusive(e) => Some(UpperFloatBound::Exclusive(e)), - }); - for facet in facets { - match facet { - Facet::Enumeration(_) - | Facet::Length(_) - | Facet::MaxLength(_) - | Facet::MinLength(_) - | Facet::Pattern(_) => return Err(make_create_err!("unsupported facet '{:?}'", facet)), - - Facet::MaxExclusive(n) => { - let new_upper = UpperFloatBound::Exclusive(match n { - Number::Integer(i) => *i as f64, - Number::Decimal(f) => *f, - }); - max = match max { - None => Some(new_upper), - Some(current) => { - if current.is_other_more_restrictive(&new_upper) { - Some(new_upper) - } else { - Some(current) - } - } - } - } - Facet::MaxInclusive(n) => { - let new_upper = UpperFloatBound::Inclusive(match n { - Number::Integer(i) => *i as f64, - Number::Decimal(f) => *f, - }); - max = match max { - None => Some(new_upper), - Some(current) => { - if current.is_other_more_restrictive(&new_upper) { - Some(new_upper) - } else { - Some(current) - } - } - } - } - Facet::MinExclusive(n) => { - let new_lower = LowerFloatBound::Exclusive(match n { - Number::Integer(i) => *i as f64, - Number::Decimal(f) => *f, - }); - min = match min { - None => Some(new_lower), - Some(current) => { - if current.is_other_more_restrictive(&new_lower) { - Some(new_lower) - } else { - Some(current) - } - } - } - } - Facet::MinInclusive(n) => { - let new_lower = LowerFloatBound::Inclusive(match n { - Number::Integer(i) => *i as f64, - Number::Decimal(f) => *f, - }); - min = match min { - None => Some(new_lower), - Some(current) => { - if current.is_other_more_restrictive(&new_lower) { - Some(new_lower) - } else { - Some(current) - } - } - } - } - } - } - Ok(Range { - min: min.and_then(|some| match some { - LowerFloatBound::Inclusive(x) => Some(Bound::Inclusive(x)), - LowerFloatBound::Exclusive(x) => Some(Bound::Exclusive(x)), - }), - max: max.and_then(|some| match some { - UpperFloatBound::Inclusive(x) => Some(Bound::Inclusive(x)), - UpperFloatBound::Exclusive(x) => Some(Bound::Inclusive(x)), - }), - }) -} - -fn parse_integer_range( - starting_range: Range, - facets: &[Facet], -) -> std::result::Result, CreateError> { - let mut min = starting_range.min.and_then(|some| match some { - Bound::Inclusive(i) => Some(LowerIntegerBound::Inclusive(i)), - Bound::Exclusive(e) => Some(LowerIntegerBound::Exclusive(e)), - }); - let mut max = starting_range.max.and_then(|some| match some { - Bound::Inclusive(i) => Some(UpperIntegerBound::Inclusive(i)), - Bound::Exclusive(e) => Some(UpperIntegerBound::Exclusive(e)), - }); - for facet in facets { - match facet { - Facet::Enumeration(_) - | Facet::Length(_) - | Facet::MaxLength(_) - | Facet::MinLength(_) - | Facet::Pattern(_) => return Err(make_create_err!("unsupported facet '{:?}'", facet)), - - Facet::MaxExclusive(n) => { - let new_upper = UpperIntegerBound::Exclusive(match n { - Number::Integer(i) => *i, - Number::Decimal(f) => *f as i64, - }); - max = match max { - None => Some(new_upper), - Some(current) => { - if current.is_other_more_restrictive(&new_upper) { - Some(new_upper) - } else { - Some(current) - } - } - } - } - Facet::MaxInclusive(n) => { - let new_upper = UpperIntegerBound::Inclusive(match n { - Number::Integer(i) => *i, - Number::Decimal(f) => *f as i64, - }); - max = match max { - None => Some(new_upper), - Some(current) => { - if current.is_other_more_restrictive(&new_upper) { - Some(new_upper) - } else { - Some(current) - } - } - } - } - Facet::MinExclusive(n) => { - let new_lower = LowerIntegerBound::Exclusive(match n { - Number::Integer(i) => *i, - Number::Decimal(f) => *f as i64, - }); - min = match min { - None => Some(new_lower), - Some(current) => { - if current.is_other_more_restrictive(&new_lower) { - Some(new_lower) - } else { - Some(current) - } - } - } - } - Facet::MinInclusive(n) => { - let new_lower = LowerIntegerBound::Inclusive(match n { - Number::Integer(i) => *i, - Number::Decimal(f) => *f as i64, - }); - min = match min { - None => Some(new_lower), - Some(current) => { - if current.is_other_more_restrictive(&new_lower) { - Some(new_lower) - } else { - Some(current) - } - } - } - } - } - } - Ok(Range { - min: min.and_then(|some| match some { - LowerIntegerBound::Inclusive(x) => Some(Bound::Inclusive(x)), - LowerIntegerBound::Exclusive(x) => Some(Bound::Exclusive(x)), - }), - max: max.and_then(|some| match some { - UpperIntegerBound::Inclusive(x) => Some(Bound::Inclusive(x)), - UpperIntegerBound::Exclusive(x) => Some(Bound::Inclusive(x)), - }), - }) -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Way too much internal stuff for figuring out ranges - -#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)] -pub enum UpperIntegerBound { - Inclusive(i64), - Exclusive(i64), -} - -impl UpperIntegerBound { - pub fn is_other_more_restrictive(&self, other: &UpperIntegerBound) -> bool { - let my_max = match self { - UpperIntegerBound::Inclusive(i) => *i, - UpperIntegerBound::Exclusive(x) => x - 1, - }; - let other_max = match other { - UpperIntegerBound::Inclusive(i) => *i, - UpperIntegerBound::Exclusive(x) => x - 1, - }; - other_max < my_max - } -} - -#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)] -pub enum LowerIntegerBound { - Inclusive(i64), - Exclusive(i64), -} - -impl LowerIntegerBound { - pub fn is_other_more_restrictive(&self, other: &LowerIntegerBound) -> bool { - let my_min = match self { - LowerIntegerBound::Inclusive(i) => *i, - LowerIntegerBound::Exclusive(x) => x + 1, - }; - let other_min = match other { - LowerIntegerBound::Inclusive(i) => *i, - LowerIntegerBound::Exclusive(x) => x + 1, - }; - other_min > my_min - } -} - -#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)] -pub enum UpperFloatBound { - Inclusive(f64), - Exclusive(f64), -} - -impl UpperFloatBound { - pub fn is_other_more_restrictive(&self, other: &UpperFloatBound) -> bool { - let (my_val, my_is_exclusive) = match self { - UpperFloatBound::Inclusive(i) => (*i, false), - UpperFloatBound::Exclusive(x) => (*x, true), - }; - let (ot_val, ot_is_exclusive) = match other { - UpperFloatBound::Inclusive(i) => (*i, false), - UpperFloatBound::Exclusive(x) => (*x, true), - }; - if my_val == ot_val { - if my_is_exclusive == ot_is_exclusive { - // they are exactly the same - return false; - } else if ot_is_exclusive { - // exclusive is more restrictive, so 'other' is more restrictive - return true; - } else { - // exclusive is more restrictive, so 'self' is more restrictive - return false; - } - } - ot_val < my_val - } -} - -#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)] -pub enum LowerFloatBound { - Inclusive(f64), - Exclusive(f64), -} - -impl LowerFloatBound { - pub fn is_other_more_restrictive(&self, other: &LowerFloatBound) -> bool { - let (my_val, my_is_exclusive) = match self { - LowerFloatBound::Inclusive(i) => (*i, false), - LowerFloatBound::Exclusive(x) => (*x, true), - }; - let (ot_val, ot_is_exclusive) = match other { - LowerFloatBound::Inclusive(i) => (*i, false), - LowerFloatBound::Exclusive(x) => (*x, true), - }; - if my_val == ot_val { - if my_is_exclusive == ot_is_exclusive { - // they are exactly the same - return false; - } else if ot_is_exclusive { - // exclusive is more restrictive, so 'other' is more restrictive - return true; - } else { - // exclusive is more restrictive, so 'self' is more restrictive - return false; - } - } - ot_val > my_val - } -} - -#[test] -fn upper_integer_bound_is_other_more_restrictive() { - #[derive(Clone, Copy, Debug)] - struct TestCase { - the_self: UpperIntegerBound, - other: UpperIntegerBound, - want: bool, - } - let test_cases = vec![ - TestCase { - the_self: UpperIntegerBound::Inclusive(1), - other: UpperIntegerBound::Inclusive(1), - want: false, - }, - TestCase { - the_self: UpperIntegerBound::Inclusive(1), - other: UpperIntegerBound::Exclusive(1), - want: true, - }, - TestCase { - the_self: UpperIntegerBound::Exclusive(1), - other: UpperIntegerBound::Inclusive(1), - want: false, - }, - TestCase { - the_self: UpperIntegerBound::Exclusive(1), - other: UpperIntegerBound::Exclusive(1), - want: false, - }, - TestCase { - the_self: UpperIntegerBound::Inclusive(10), - other: UpperIntegerBound::Exclusive(20), - want: false, - }, - TestCase { - the_self: UpperIntegerBound::Inclusive(20), - other: UpperIntegerBound::Exclusive(10), - want: true, - }, - ]; - for t in &test_cases { - let got = t.the_self.is_other_more_restrictive(&t.other); - assert_eq!(got, t.want, "'{:?}", t) - } -} - -#[test] -fn lower_integer_bound_is_other_more_restrictive() { - #[derive(Clone, Copy, Debug)] - struct TestCase { - the_self: LowerIntegerBound, - other: LowerIntegerBound, - want: bool, - } - let test_cases = vec![ - TestCase { - the_self: LowerIntegerBound::Inclusive(1), - other: LowerIntegerBound::Inclusive(1), - want: false, - }, - TestCase { - the_self: LowerIntegerBound::Inclusive(1), - other: LowerIntegerBound::Exclusive(1), - want: true, - }, - TestCase { - the_self: LowerIntegerBound::Exclusive(1), - other: LowerIntegerBound::Inclusive(1), - want: false, - }, - TestCase { - the_self: LowerIntegerBound::Exclusive(1), - other: LowerIntegerBound::Exclusive(1), - want: false, - }, - TestCase { - the_self: LowerIntegerBound::Inclusive(10), - other: LowerIntegerBound::Exclusive(20), - want: true, - }, - TestCase { - the_self: LowerIntegerBound::Inclusive(20), - other: LowerIntegerBound::Exclusive(10), - want: false, - }, - ]; - for t in &test_cases { - let got = t.the_self.is_other_more_restrictive(&t.other); - assert_eq!(got, t.want, "'{:?}", t) - } -} - -#[test] -fn upper_float_bound_is_other_more_restrictive() { - #[derive(Clone, Copy, Debug)] - struct TestCase { - the_self: UpperFloatBound, - other: UpperFloatBound, - want: bool, - } - let test_cases = vec![ - TestCase { - the_self: UpperFloatBound::Inclusive(1.0), - other: UpperFloatBound::Inclusive(1.0), - want: false, - }, - TestCase { - the_self: UpperFloatBound::Inclusive(1.0), - other: UpperFloatBound::Exclusive(1.0), - want: true, - }, - TestCase { - the_self: UpperFloatBound::Exclusive(1.0), - other: UpperFloatBound::Inclusive(1.0), - want: false, - }, - TestCase { - the_self: UpperFloatBound::Exclusive(1.0), - other: UpperFloatBound::Exclusive(1.0), - want: false, - }, - TestCase { - the_self: UpperFloatBound::Inclusive(0.01), - other: UpperFloatBound::Exclusive(0.02), - want: false, - }, - TestCase { - the_self: UpperFloatBound::Inclusive(0.02), - other: UpperFloatBound::Exclusive(0.01), - want: true, - }, - ]; - for t in &test_cases { - let got = t.the_self.is_other_more_restrictive(&t.other); - assert_eq!(got, t.want, "'{:?}", t) - } -} - -#[test] -fn lower_float_bound_is_other_more_restrictive() { - #[derive(Clone, Copy, Debug)] - struct TestCase { - the_self: LowerFloatBound, - other: LowerFloatBound, - want: bool, - } - let test_cases = vec![ - TestCase { - the_self: LowerFloatBound::Inclusive(1.0), - other: LowerFloatBound::Inclusive(1.0), - want: false, - }, - TestCase { - the_self: LowerFloatBound::Inclusive(1.0), - other: LowerFloatBound::Exclusive(1.0), - want: true, - }, - TestCase { - the_self: LowerFloatBound::Exclusive(1.0), - other: LowerFloatBound::Inclusive(1.0), - want: false, - }, - TestCase { - the_self: LowerFloatBound::Exclusive(1.0), - other: LowerFloatBound::Exclusive(1.0), - want: false, - }, - TestCase { - the_self: LowerFloatBound::Inclusive(0.01), - other: LowerFloatBound::Exclusive(0.02), - want: true, - }, - TestCase { - the_self: LowerFloatBound::Inclusive(0.02), - other: LowerFloatBound::Exclusive(0.01), - want: false, - }, - ]; - for t in &test_cases { - let got = t.the_self.is_other_more_restrictive(&t.other); - assert_eq!(got, t.want, "'{:?}", t) - } -} diff --git a/gen/version-b/src/model/enumeration.rs b/gen/version-b/src/model/enumeration.rs deleted file mode 100644 index ad7860cfd..000000000 --- a/gen/version-b/src/model/enumeration.rs +++ /dev/null @@ -1,29 +0,0 @@ -use crate::model::builtin::BuiltinString; -use crate::model::symbol::Symbol; - -#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)] -pub struct Enumeration { - pub name: Symbol, - pub members: Vec, - pub documentation: String, - pub default: Symbol, - /// There are enums that are handled specially because they were part of an element that allowed - /// for an "other" field that could hold a string. If `other_field.is_some()`, it means that the - /// enum behaves like a variant where some value can be held in a field that might be named, for - /// example `other`. For an example of an 'enum' like this, see the `Dynamics` element in - /// `musicxml.xsd`, which uses empty element choices for its enum values and an - /// `whatever` choice to allow for any string value. - pub other_field: Option, -} - -/// For cases where something akin to an enum was defined in the XSD, such that a list of possible -/// string values was given, but an 'other' field is allowed as an escape hatch. Here we define the -/// name of that 'other' field along with its string type. -#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)] -pub struct OtherField { - pub name: Symbol, - pub type_: BuiltinString, - /// A language like Rust wouldn't need this, but in, e.g. C++, an enum cannot contain a value, - /// so the enum and the potential 'other' value need to be 'wrapped' together in some way. - pub wrapper_class_name: Symbol, -} diff --git a/gen/version-b/src/model/mod.rs b/gen/version-b/src/model/mod.rs deleted file mode 100644 index 6d3376f1c..000000000 --- a/gen/version-b/src/model/mod.rs +++ /dev/null @@ -1,115 +0,0 @@ -#[macro_use] -pub mod create; - -pub mod builtin; -pub mod creator; -pub mod default_create; -pub mod enumeration; -pub mod post_process; -pub mod scalar; -pub mod symbol; -pub mod transform; - -use crate::error::Result; -use crate::model::create::{Create, CreateError, CreateResult}; -use crate::model::enumeration::Enumeration; -use crate::model::scalar::{DerivedSimpleTypeData, ScalarNumeric, ScalarString, UnionData}; -use crate::model::symbol::Symbol; -use crate::xsd::primitives::BaseType; -use crate::xsd::restriction::Facet; -use crate::xsd::simple_type::{Payload, SimpleType}; -use crate::xsd::{simple_type, Entry, Xsd}; -pub use default_create::DefaultCreate; -use std::borrow::Borrow; -use std::collections::HashMap; -use std::ops::Deref; - -#[derive(Debug, Clone, PartialEq, PartialOrd)] -pub enum Def { - Enumeration(Enumeration), - ScalarString(ScalarString), - ScalarNumber(ScalarNumeric), - CustomScalarString(ScalarString), - DerivedSimpleType(DerivedSimpleTypeData), - UnionSimpleType(UnionData), -} - -impl Def { - pub fn name(&self) -> &Symbol { - match self { - Def::Enumeration(x) => &x.name, - Def::ScalarString(x) => &x.name, - Def::ScalarNumber(x) => x.name(), - Def::CustomScalarString(x) => &x.name, - Def::DerivedSimpleType(x) => &x.name, - Def::UnionSimpleType(x) => &x.name, - } - } -} - -#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)] -pub enum Shape { - Simple, - Complex, - // TODO - not sure - // AttributeGroup, - // Element -} - -impl Default for Shape { - fn default() -> Self { - Shape::Simple - } -} - -#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Default)] -pub struct Ipseity { - shape: Shape, - name: String, -} - -#[derive(Debug, Clone, Default)] -pub struct Model { - map: HashMap, -} - -impl Model { - pub fn add(&mut self, def: Def) -> Result<()> { - let shape = match def { - Def::Enumeration(_) => Shape::Simple, - Def::ScalarString(_) => Shape::Simple, - Def::ScalarNumber(_) => Shape::Simple, - Def::CustomScalarString(_) => Shape::Simple, - Def::DerivedSimpleType(_) => Shape::Simple, - Def::UnionSimpleType(_) => Shape::Simple, - }; - let ipseity = Ipseity { - shape, - name: def.name().original().into(), - }; - match self.map.insert(ipseity.clone(), def) { - None => Ok(()), - Some(_) => raise!("duplicate item {:?}", ipseity), - } - } - - pub fn get_ips(&self, ipseity: &Ipseity) -> Option<&Def> { - self.map.get(ipseity) - } - - pub fn get>(&self, shape: Shape, name: S) -> Option<&Def> { - let ips = Ipseity { - shape, - name: name.as_ref().into(), - }; - self.get_ips(&ips) - } - - pub fn defs(&self) -> impl Iterator { - self.map.values() - } - - pub fn iter(&self) -> impl Iterator { - self.map.iter() - } -} diff --git a/gen/version-b/src/model/post_process.rs b/gen/version-b/src/model/post_process.rs deleted file mode 100644 index 737f753eb..000000000 --- a/gen/version-b/src/model/post_process.rs +++ /dev/null @@ -1,12 +0,0 @@ -use crate::model::create::CreateError; -use crate::model::Def; -use crate::xsd::Xsd; - -/// Changes a `Model` -pub trait PostProcess { - /// The name of this `PostProcess` object (for debugging). - fn name(&self) -> &'static str; - - /// Transforms and `Entry`. - fn process(&self, model: &Def, xsd: &Xsd) -> std::result::Result; -} diff --git a/gen/version-b/src/model/scalar.rs b/gen/version-b/src/model/scalar.rs deleted file mode 100644 index c2df479b0..000000000 --- a/gen/version-b/src/model/scalar.rs +++ /dev/null @@ -1,98 +0,0 @@ -use crate::error::Result; -use crate::model::builtin::BuiltinString; -use crate::model::symbol::Symbol; -use crate::xsd::primitives::{BaseType, Character, Numeric}; -use std::fmt::Debug; -use std::num::NonZeroU64; - -#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Default)] -pub struct ScalarString { - pub name: Symbol, - pub base_type: Character, - pub documentation: String, - pub min_length: Option, - pub max_length: Option, - pub pattern: Option, -} - -#[derive(Debug, Clone, PartialEq, PartialOrd)] -pub enum ScalarNumeric { - Decimal(NumericData), - Integer(NumericData), -} - -impl Default for ScalarNumeric { - fn default() -> Self { - ScalarNumeric::Integer(NumericData::default()) - } -} - -impl ScalarNumeric { - pub fn name(&self) -> &Symbol { - match self { - ScalarNumeric::Decimal(x) => &x.name, - ScalarNumeric::Integer(x) => &x.name, - } - } -} - -#[derive(Debug, Clone, PartialEq, PartialOrd)] -pub enum Bound -where - T: Debug + Clone + Copy + PartialEq + PartialOrd + Default, -{ - Inclusive(T), - Exclusive(T), -} - -impl Default for Bound -where - T: Debug + Clone + Copy + PartialEq + PartialOrd + Default, -{ - fn default() -> Self { - Bound::Inclusive(Default::default()) - } -} - -#[derive(Debug, Clone, PartialEq, PartialOrd, Default)] -pub struct Range -where - T: Debug + Clone + Copy + PartialEq + PartialOrd + Default, -{ - pub min: Option>, - pub max: Option>, -} - -impl Range -where - T: Debug + Clone + Copy + PartialEq + PartialOrd + Default, -{ - pub fn new(min: Option>, max: Option>) -> Self { - Self { min, max } - } -} - -#[derive(Debug, Clone, PartialEq, PartialOrd, Default)] -pub struct NumericData -where - T: Debug + Clone + Copy + PartialEq + PartialOrd + Default, -{ - pub name: Symbol, - pub base_type: Numeric, - pub documentation: String, - pub range: Range, -} - -#[derive(Debug, Clone, PartialEq, PartialOrd, Default)] -pub struct DerivedSimpleTypeData { - pub name: Symbol, - pub base_type: String, - pub documentation: String, -} - -#[derive(Debug, Clone, PartialEq, PartialOrd, Default)] -pub struct UnionData { - pub name: Symbol, - pub members: Vec, - pub documentation: String, -} diff --git a/gen/version-b/src/model/symbol.rs b/gen/version-b/src/model/symbol.rs deleted file mode 100644 index 896ed5094..000000000 --- a/gen/version-b/src/model/symbol.rs +++ /dev/null @@ -1,126 +0,0 @@ -use crate::utils::string_stuff::tokenize; -use std::borrow::Cow; - -/// Holds a name or symbol in the many ways that it may need to be 'spelled' during code generation. -#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Default)] -pub struct Symbol { - /// The original symbol, as defined in the XSD document. e.g. `foo bar`. - original: String, - /// An optional renaming of the symbol. `foo baz` - renamed_to: String, - /// Snake case, e.g. `foo_baz`. - snake: String, - /// Screaming snake case, e.g. `FOO_BAZ`. - screaming_snake: String, - /// Camel case, e.g. `fooBaz`. - camel: String, - /// Pascal case, e.g. `FooBaz`. - pascal: String, -} - -impl Symbol { - pub fn original(&self) -> &str { - self.original.as_str() - } - - pub fn renamed_to(&self) -> &str { - self.renamed_to.as_str() - } - - pub fn screaming_snake(&self) -> &str { - self.screaming_snake.as_str() - } - - pub fn snake(&self) -> &str { - self.snake.as_str() - } - - pub fn camel(&self) -> &str { - self.camel.as_str() - } - - pub fn pascal(&self) -> &str { - self.pascal.as_str() - } - - pub fn new(original: S) -> Self - where - S: AsRef, - { - let tokens = tokenize(original.as_ref()); - Self::new_with_tokens(original, tokens.as_slice()) - } - - pub fn set_camel>(&mut self, value: S) { - self.camel = value.as_ref().into(); - } - - pub fn replace>(&mut self, replacement: S) { - let replace_with = Symbol::new(replacement); - *self = Symbol { - original: self.original.clone(), - ..replace_with - } - } - - pub fn new_with_tokens(original: S, tokenized: &[String]) -> Self - where - S: AsRef, - { - let snake: String = tokenized.join("_").to_lowercase(); - let screaming_snake = snake.to_uppercase(); - let pascal = tokenized - .iter() - .map(|s| { - let mut c = s.chars(); - match c.next() { - None => String::new(), - Some(f) => f.to_uppercase().chain(c).collect(), - } - }) - .collect::>() - .join(""); - let camel = { - let mut c = pascal.chars(); - match c.next() { - None => String::new(), - Some(f) => f.to_lowercase().chain(c).collect(), - } - }; - Self { - original: original.as_ref().to_owned(), - renamed_to: original.as_ref().to_owned(), - snake, - screaming_snake, - camel, - pascal, - } - } -} - -#[test] -fn symbol_1() { - let original = "bones the cat"; - let tokenized = vec!["bones", "the", "cat"]; - let symbol = Symbol::new(original); - assert_eq!(symbol.original(), original); - assert_eq!(symbol.renamed_to(), original); - assert_eq!(symbol.snake(), "bones_the_cat"); - assert_eq!(symbol.screaming_snake(), "BONES_THE_CAT"); - assert_eq!(symbol.camel(), "bonesTheCat"); - assert_eq!(symbol.pascal(), "BonesTheCat"); -} - -#[test] -fn symbol_2() { - let original = "bones the cat"; - let tokenized = vec!["bones", "the", "cat"]; - let mut symbol = Symbol::new(original); - symbol.replace("bleep bloop"); - assert_eq!(symbol.original(), original); - assert_eq!(symbol.renamed_to(), "bleep bloop"); - assert_eq!(symbol.snake(), "bleep_bloop"); - assert_eq!(symbol.screaming_snake(), "BLEEP_BLOOP"); - assert_eq!(symbol.camel(), "bleepBloop"); - assert_eq!(symbol.pascal(), "BleepBloop"); -} diff --git a/gen/version-b/src/model/transform.rs b/gen/version-b/src/model/transform.rs deleted file mode 100644 index cd52c8162..000000000 --- a/gen/version-b/src/model/transform.rs +++ /dev/null @@ -1,17 +0,0 @@ -use crate::model::create::CreateError; -use crate::model::Def; -use crate::xsd::{Entry, Xsd}; -use std::fmt::{Display, Formatter}; - -/// # Transform Trait -/// -/// An object that takes a top-level `Entry` from the XSD document, alters it in some way, and -/// returns the altered `Entry`. -/// -pub trait Transform { - /// The name of this `Transform` object (for debugging). - fn name(&self) -> &'static str; - - /// Transforms and `Entry`. - fn transform(&self, entry: &Entry, xsd: &Xsd) -> std::result::Result; -} diff --git a/gen/version-b/src/utils/mod.rs b/gen/version-b/src/utils/mod.rs deleted file mode 100644 index 6849a89ea..000000000 --- a/gen/version-b/src/utils/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod string_stuff; diff --git a/gen/version-b/src/utils/string_stuff.rs b/gen/version-b/src/utils/string_stuff.rs deleted file mode 100644 index 380b70f31..000000000 --- a/gen/version-b/src/utils/string_stuff.rs +++ /dev/null @@ -1,627 +0,0 @@ -// TODO - these string constants are inflexible. -pub const LINE_WIDTH: usize = 100; -pub const INDENT: &str = " "; -pub const DOC_COMMENT: &str = "///"; - -use crate::error::Result; -use std::borrow::Cow; -use std::cmp::Ordering; -use std::fmt::{Display, Formatter}; -use std::io::{Cursor, Write}; - -#[derive(Debug, Clone, Eq, Ord, Default)] -pub struct Altered { - pub value: String, - pub original: String, -} - -impl Display for Altered { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "{}({})", self.value, self.original) - } -} - -impl PartialOrd for Altered { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.value.cmp(&other.value)) - } -} - -impl PartialEq for Altered { - fn eq(&self, other: &Altered) -> bool { - self.value == other.value - } -} - -#[derive(Debug, Clone, Eq, Ord)] -pub enum Symbol { - Unaltered(String), - Altered(Altered), -} - -impl PartialOrd for Symbol { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.value().cmp(other.value())) - } -} - -impl PartialEq for Symbol { - fn eq(&self, other: &Symbol) -> bool { - self.value() == other.value() - } -} - -impl Symbol { - pub fn new>(s: S) -> Symbol { - Symbol::Unaltered(s.as_ref().to_string()) - } - - /// If `altered` and `original` are equal, returns `Unaltered`, else returns `Altered`. - pub fn from(altered: S1, original: S2) -> Self - where - S1: AsRef, - S2: AsRef, - { - if altered.as_ref() == original.as_ref() { - Symbol::new(original.as_ref()) - } else { - Symbol::Altered(Altered { - value: altered.as_ref().into(), - original: original.as_ref().into(), - }) - } - } - - pub fn value(&self) -> &str { - match self { - Symbol::Unaltered(s) => s.as_str(), - Symbol::Altered(a) => a.value.as_str(), - } - } - - pub fn original(&self) -> &str { - match self { - Symbol::Unaltered(s) => s.as_str(), - Symbol::Altered(a) => a.original.as_str(), - } - } -} - -pub fn tokenize>(s: S) -> Vec { - let mut tokens = Vec::new(); - let mut buf = String::new(); - let mut is_word_start = true; - let mut was_lowercase = true; - let mut was_digit = false; - for c in s.as_ref().chars() { - if was_lowercase && c.is_uppercase() { - is_word_start = true; - } - if c.is_ascii_digit() { - is_word_start = !was_digit; - } - if !c.is_alphanumeric() { - is_word_start = true; - } else if is_word_start { - if !buf.is_empty() { - tokens.push(buf); - buf = String::new(); - } - buf.push(c.to_ascii_lowercase()); - is_word_start = false; - } else { - buf.push(c.to_ascii_lowercase()); - is_word_start = false; - } - was_lowercase = !c.is_ascii_digit() && c.is_lowercase(); - was_digit = c.is_ascii_digit(); - } - if !buf.is_empty() { - tokens.push(buf); - } - tokens -} - -pub fn pascal_case>(s: S) -> Symbol { - case(s, Case::Pascal) -} - -pub fn camel_case>(s: S) -> Symbol { - case(s, Case::Camel) -} - -#[derive(Debug, Eq, PartialEq, Ord, PartialOrd)] -enum Case { - Camel, - Pascal, -} - -fn case>(s: S, cs: Case) -> Symbol { - let mut out = String::new(); - let mut is_next_upper = cs == Case::Pascal; - for c in s.as_ref().chars() { - if !c.is_alphanumeric() { - is_next_upper = true; - } else if c.is_ascii_digit() { - out.push(c); - is_next_upper = false; - } else if is_next_upper { - out.push(c.to_ascii_uppercase()); - is_next_upper = false; - } else { - out.push(c.to_ascii_lowercase()); - is_next_upper = false; - } - } - Symbol::from(out, s) -} - -pub fn sep>(s: S, subtract_indentations: usize) -> String { - let mut out = DOC_COMMENT.to_owned(); - let width = LINE_WIDTH - (subtract_indentations * 4); - let s = s.as_ref(); - if !s.is_empty() { - out.push_str(format!(" {} ", s).as_str()); - } - loop { - if out.len() >= width { - break; - } - out.push('/'); - } - out -} - -pub fn documentation>(documentation: S, indents: usize) -> Result { - let mut c = Cursor::new(Vec::new()); - wrap!(write_documentation(&mut c, documentation, indents))?; - Ok(String::from_utf8_lossy(c.get_ref().as_slice()).to_string()) -} - -pub fn write_documentation(w: &mut W, documentation: S, indents: usize) -> std::io::Result<()> -where - W: Write, - S: AsRef, -{ - let orig = documentation.as_ref(); - let orig_lines = orig.lines(); - let mut consec_empty = 0; - let mut clean_lines: Vec = Vec::new(); - for line in orig_lines { - let mut line: String = line.into(); - let line = line.replace("\t", " "); - if is_empty(&line) { - if consec_empty < 2 { - clean_lines.push(line.clone()); - } - consec_empty += 1; - } else { - clean_lines.push(line.clone()); - consec_empty = 0; - } - // clean_lines.push(line.clone()); - } - let width = LINE_WIDTH - (DOC_COMMENT.len() + 1) - (INDENT.len() * indents); - let mut final_lines: Vec> = Vec::new(); - for line in &clean_lines { - if is_empty(line.as_str()) { - final_lines.push(Cow::Borrowed(line)) - } - let mut result = textwrap::wrap(line.as_str(), width); - final_lines.append(&mut result); - } - consec_empty = 0; - for (i, line) in final_lines.iter().enumerate() { - let line = line.as_ref(); - let line_is_empty = is_empty(line); - let last_line = i == final_lines.len() - 1; - if line_is_empty && consec_empty > 0 { - consec_empty += 1; - continue; - } - if line_is_empty { - linestart(w, indents, false)?; - consec_empty += 1; - } else { - linestart(w, indents, true)?; - consec_empty = 0; - } - if last_line { - write!(w, "{}", line)?; - } else { - write!(w, "{}\n", line)?; - } - } - Ok(()) -} - -fn is_empty>(line: S) -> bool { - for c in line.as_ref().chars() { - if !c.is_whitespace() { - return false; - } - } - true -} - -pub fn linestart(w: &mut W, indents: usize, add_space: bool) -> std::io::Result { - let mut pos: usize = 0; - for _ in 0..indents { - write!(w, "{}", INDENT)?; - pos += INDENT.len(); - } - write!(w, "{}", DOC_COMMENT)?; - pos += DOC_COMMENT.len(); - if add_space { - write!(w, " ")?; - pos += 1; - } - Ok(pos) -} - -pub fn words>(s: S) -> Vec { - let mut result = Vec::new(); - let mut consecutive_newlines = 0; - let mut word = String::new(); - for c in s.as_ref().chars() { - if c.is_whitespace() { - if !word.is_empty() { - result.push(word.clone()); - word.clear(); - } - if c == '\n' { - if consecutive_newlines == 0 { - result.push("\n".into()); - } - consecutive_newlines += 1; - continue; - } - } else { - word.push(c); - } - consecutive_newlines = 0; - } - if !word.is_empty() { - result.push(word); - } - result -} - -#[cfg(test)] -mod tests { - use super::{documentation, words, Symbol}; - use crate::utils::string_stuff::tokenize; - use std::io::Cursor; - - #[test] - fn pascal_case_clef_tab() { - let input = "TAB"; - let got = super::pascal_case(input); - let want = "Tab".to_string(); - assert_eq!(got.value(), want); - if let Symbol::Altered(altered) = got { - assert_eq!(altered.original.as_str(), input); - } else { - panic!("expected Symbol::Altered"); - } - } - - #[test] - fn camel_case_clef_tab() { - let input = "TAB"; - let got = super::camel_case(input); - let want = "tab".to_string(); - assert_eq!(got.value(), want); - if let Symbol::Altered(altered) = got { - assert_eq!(altered.original.as_str(), input); - } else { - panic!("expected Symbol::Altered"); - } - } - - #[test] - fn pascal_case_step_a_lower() { - let input = "a"; - let got = super::pascal_case(input); - let want = "A".to_string(); - assert_eq!(got.value(), want); - if let Symbol::Altered(altered) = got { - assert_eq!(altered.original.as_str(), input); - } else { - panic!("expected Symbol::Altered"); - } - } - - #[test] - fn camel_case_step_a_lower() { - let input = "a"; - let got = super::camel_case(input); - let want = "a".to_string(); - assert_eq!(got.value(), want); - if let Symbol::Unaltered(unaltered) = got { - assert_eq!(unaltered.as_str(), input); - } else { - panic!("expected Symbol::Unaltered"); - } - } - - #[test] - fn pascal_case_wind_chimes() { - let input = "wind cHIMES"; - let got = super::pascal_case(input); - let want = "WindChimes".to_string(); - assert_eq!(got.value(), want); - if let Symbol::Altered(altered) = got { - assert_eq!(altered.original.as_str(), input); - } else { - panic!("expected Symbol::Altered"); - } - } - - #[test] - fn camel_case_step_wind_chimes() { - let input = "wind cHIMES"; - let got = super::camel_case(input); - let want = "windChimes".to_string(); - assert_eq!(got.value(), want); - if let Symbol::Altered(altered) = got { - assert_eq!(altered.original.as_str(), input); - } else { - panic!("expected Symbol::Altered"); - } - } - - #[test] - fn pascal_case_chord_kind() { - let input = "dominant-11th"; - let got = super::pascal_case(input); - let want = "Dominant11th".to_string(); - assert_eq!(got.value(), want); - if let Symbol::Altered(altered) = got { - assert_eq!(altered.original.as_str(), input); - } else { - panic!("expected Symbol::Altered"); - } - } - - #[test] - fn camel_case_step_chord_kind() { - let input = "DomInAnt 1 1th"; - let got = super::camel_case(input); - let want = "dominant11th".to_string(); - assert_eq!(got.value(), want); - if let Symbol::Altered(altered) = got { - assert_eq!(altered.original.as_str(), input); - } else { - panic!("expected Symbol::Altered"); - } - } - - #[test] - fn get_words() { - let input = r#"Here is a sentence. And another sentence, which has a comma: - With extra spaces and newlines, etc."#; - let got = words(input); - let want = vec![ - "Here".to_owned(), - "is".to_owned(), - "a".to_owned(), - "sentence.".to_owned(), - "And".to_owned(), - "another".to_owned(), - "sentence,".to_owned(), - "which".to_owned(), - "has".to_owned(), - "a".to_owned(), - "comma:".to_owned(), - "\n".to_owned(), - "With".to_owned(), - "extra".to_owned(), - "spaces".to_owned(), - "and".to_owned(), - "newlines,".to_owned(), - "etc.".to_owned(), - ]; - assert_eq!(got.len(), want.len()); - for (i, want_word) in want.iter().enumerate() { - let got_word = got.get(i).unwrap(); - assert_eq!(got_word, want_word); - } - } - - #[test] - fn write_documentation() { - let input = r#"Here is a sentence. And another sentence, which has a comma: - With extra spaces and newlines, etc."#; - let mut w = Cursor::new(vec![0; 15]); - super::write_documentation(&mut w, input, 1).unwrap(); - let got = String::from_utf8_lossy(w.get_ref()); - let want = r#" /// Here is a sentence. And another sentence, which has a comma: - /// With extra spaces and newlines, etc."#; - assert_eq!(got, want); - } - - #[test] - fn write_documentation_wrap() { - let input = "Here is a sentence. And another sentence, which has a comma: without a \ - newline it goes on for a long time and must be wrapped it's really quite remarkable"; - let mut w = Cursor::new(vec![0; 15]); - super::write_documentation(&mut w, input, 1).unwrap(); - let got = String::from_utf8_lossy(w.get_ref()); - let want = r#" /// Here is a sentence. And another sentence, which has a comma: without a newline it goes on - /// for a long time and must be wrapped it's really quite remarkable"#; - assert_eq!(got, want); - } - - #[test] - fn write_documentation_newlines() { - let input = "a\nb\n\nc\n\n\n\nd"; - let mut w = Cursor::new(vec![0; 15]); - super::write_documentation(&mut w, input, 1).unwrap(); - let got = String::from_utf8_lossy(w.get_ref()); - let want = r#" /// a - /// b - /// - /// c - /// - /// d"#; - assert_eq!(got, want); - } - - #[test] - fn tokenize_strings() { - struct TestCase { - input: &'static str, - want: Vec, - } - let mut test_cases = vec![ - TestCase { - input: "modeValue", - want: vec!["mode".to_owned(), "value".to_owned()], - }, - TestCase { - input: "DomInAnt11th", - want: vec![ - "dom".to_owned(), - "in".to_owned(), - "ant".to_owned(), - "11th".to_owned(), - ], - }, - TestCase { - input: "dominant11th", - want: vec!["dominant".to_owned(), "11th".to_owned()], - }, - ]; - for test_case in &test_cases { - let got = tokenize(test_case.input); - assert_eq!(got, test_case.want); - } - } - - const DYNAMICS_DOCUMENTATION: &str = r#"Dynamics can be associated either with a note or a general musical direction. To avoid inconsistencies between and amongst the letter abbreviations for dynamics (what is sf vs. sfz, standing alone or with a trailing dynamic that is not always piano), we use the actual letters as the names of these dynamic elements. The other-dynamics element allows other dynamic marks that are not covered here, but many of those should perhaps be included in a more general musical direction element. Dynamics elements may also be combined to create marks not covered by a single element, such as sfmp. - - - - -These letter dynamic symbols are separated from crescendo, decrescendo, and wedge indications. Dynamic representation is inconsistent in scores. Many things are assumed by the composer and left out, such as returns to original dynamics. Systematic representations are quite complex: for example, Humdrum has at least 3 representation formats related to dynamics. The MusicXML format captures what is in the score, but does not try to be optimal for analysis or synthesis of dynamics."#; - const DYNAMICS_EXPECTED: &str = r#" /// Dynamics can be associated either with a note or a general musical direction. To avoid - /// inconsistencies between and amongst the letter abbreviations for dynamics (what is sf - /// vs. sfz, standing alone or with a trailing dynamic that is not always piano), we use the - /// actual letters as the names of these dynamic elements. The other-dynamics element allows - /// other dynamic marks that are not covered here, but many of those should perhaps be - /// included in a more general musical direction element. Dynamics elements may also be - /// combined to create marks not covered by a single element, such as sfmp. - /// - /// These letter dynamic symbols are separated from crescendo, decrescendo, and wedge - /// indications. Dynamic representation is inconsistent in scores. Many things are assumed - /// by the composer and left out, such as returns to original dynamics. Systematic - /// representations are quite complex: for example, Humdrum has at least 3 representation - /// formats related to dynamics. The MusicXML format captures what is in the score, but does - /// not try to be optimal for analysis or synthesis of dynamics."#; - - #[test] - fn test_documentation() { - let got = documentation(DYNAMICS_DOCUMENTATION, 2).unwrap(); - let want = DYNAMICS_EXPECTED; - assert_eq!(got, want); - } - - const KIND_DOCUMENTATION: &str = r#"A kind-value indicates the type of chord. Degree elements can then add, subtract, or alter from these starting points. Values include: - -Triads: - major (major third, perfect fifth) - minor (minor third, perfect fifth) - augmented (major third, augmented fifth) - diminished (minor third, diminished fifth) -Sevenths: - dominant (major triad, minor seventh) - major-seventh (major triad, major seventh) - minor-seventh (minor triad, minor seventh) - diminished-seventh (diminished triad, diminished seventh) - augmented-seventh (augmented triad, minor seventh) - half-diminished (diminished triad, minor seventh) - major-minor (minor triad, major seventh) -Sixths: - major-sixth (major triad, added sixth) - minor-sixth (minor triad, added sixth) -Ninths: - dominant-ninth (dominant-seventh, major ninth) - major-ninth (major-seventh, major ninth) - minor-ninth (minor-seventh, major ninth) -11ths (usually as the basis for alteration): - dominant-11th (dominant-ninth, perfect 11th) - major-11th (major-ninth, perfect 11th) - minor-11th (minor-ninth, perfect 11th) -13ths (usually as the basis for alteration): - dominant-13th (dominant-11th, major 13th) - major-13th (major-11th, major 13th) - minor-13th (minor-11th, major 13th) -Suspended: - suspended-second (major second, perfect fifth) - suspended-fourth (perfect fourth, perfect fifth) -Functional sixths: - Neapolitan - Italian - French - German -Other: - pedal (pedal-point bass) - power (perfect fifth) - Tristan - -The "other" kind is used when the harmony is entirely composed of add elements. The "none" kind is used to explicitly encode absence of chords or functional harmony."#; - const KIND_EXPECTED: &str = r#" /// A kind-value indicates the type of chord. Degree elements can then add, subtract, or - /// alter from these starting points. Values include: - /// - /// Triads: - /// major (major third, perfect fifth) - /// minor (minor third, perfect fifth) - /// augmented (major third, augmented fifth) - /// diminished (minor third, diminished fifth) - /// Sevenths: - /// dominant (major triad, minor seventh) - /// major-seventh (major triad, major seventh) - /// minor-seventh (minor triad, minor seventh) - /// diminished-seventh (diminished triad, diminished seventh) - /// augmented-seventh (augmented triad, minor seventh) - /// half-diminished (diminished triad, minor seventh) - /// major-minor (minor triad, major seventh) - /// Sixths: - /// major-sixth (major triad, added sixth) - /// minor-sixth (minor triad, added sixth) - /// Ninths: - /// dominant-ninth (dominant-seventh, major ninth) - /// major-ninth (major-seventh, major ninth) - /// minor-ninth (minor-seventh, major ninth) - /// 11ths (usually as the basis for alteration): - /// dominant-11th (dominant-ninth, perfect 11th) - /// major-11th (major-ninth, perfect 11th) - /// minor-11th (minor-ninth, perfect 11th) - /// 13ths (usually as the basis for alteration): - /// dominant-13th (dominant-11th, major 13th) - /// major-13th (major-11th, major 13th) - /// minor-13th (minor-11th, major 13th) - /// Suspended: - /// suspended-second (major second, perfect fifth) - /// suspended-fourth (perfect fourth, perfect fifth) - /// Functional sixths: - /// Neapolitan - /// Italian - /// French - /// German - /// Other: - /// pedal (pedal-point bass) - /// power (perfect fifth) - /// Tristan - /// - /// The "other" kind is used when the harmony is entirely composed of add elements. The - /// "none" kind is used to explicitly encode absence of chords or functional harmony."#; - - #[test] - fn test_kind_documentation() { - let got = documentation(KIND_DOCUMENTATION, 2).unwrap(); - let want = KIND_EXPECTED; - assert_eq!(got, want); - } -} diff --git a/gen/version-b/src/xsd/annotation.rs b/gen/version-b/src/xsd/annotation.rs deleted file mode 100644 index 22f4831b7..000000000 --- a/gen/version-b/src/xsd/annotation.rs +++ /dev/null @@ -1,124 +0,0 @@ -#[macro_use] -use crate::error::Result; -use crate::xsd::constants::{ANNOTATION, APP_INFO, DOCUMENTATION, NAME}; -use crate::xsd::id::{Id, Lineage, RootNodeType}; -use crate::xsd::Xsd; -use std::fmt::{Debug, Formatter}; - -#[derive(Clone, Debug)] -pub struct Annotation { - pub id: Id, - pub items: Vec, -} - -#[derive(Clone, Debug)] -pub enum Item { - Documentation(String), - AppInfo(String), -} - -impl Annotation { - pub fn documentation(&self) -> String { - for item in &self.items { - if let Item::Documentation(s) = &item { - return s.clone(); - } - } - "".to_owned() - } - - pub fn from_xml(node: &exile::Element, lineage: Lineage, xsd: &Xsd) -> Result { - check!(ANNOTATION, node, xsd)?; - let (id, lineage) = Id::make(lineage, node)?; - let mut items = Vec::new(); - for inner in node.children() { - let t = inner.name.as_str(); - if let Some(s) = inner.text() { - match t { - DOCUMENTATION => items.push(Item::Documentation(s)), - APP_INFO => items.push(Item::AppInfo(s)), - _ => { - return raise!( - "expected either '{}' or '{}', got '{}'", - DOCUMENTATION, - APP_INFO, - t - ); - } - } - } - } - Ok(Annotation { id, items }) - } -} - -#[test] -fn parse() { - let want_index: u64 = 13; - let want_name = "4594507136952412519"; - let want_doc = "bishop is sleeping."; - let xml = exile::Element { - namespace: Some("xs".to_owned()), - name: ANNOTATION.to_owned(), - attributes: Default::default(), - nodes: vec![exile::Node::Element(exile::Element { - namespace: Some("xs".to_owned()), - name: DOCUMENTATION.to_owned(), - attributes: Default::default(), - nodes: vec![exile::Node::Text(want_doc.to_owned())], - })], - }; - - let annotation = - Annotation::from_xml(&xml, Lineage::Index(want_index), &Xsd::new("xs")).unwrap(); - let got_doc = annotation.documentation(); - assert_eq!(got_doc.as_str(), want_doc); - let got_index = annotation.id.index().unwrap(); - assert_eq!(got_index, want_index); - let got_name = annotation.id.name(); - assert_eq!(got_name, want_name); - let got_type = annotation.id.root_node_type().unwrap(); - assert_eq!(got_type, RootNodeType::Annotation); -} - -#[test] -fn parse_foo_err() { - let want_index: u64 = 13; - let want_name = "4594507136952412519"; - let want_doc = "bishop is sleeping."; - let xml = exile::Element { - namespace: Some("xs".to_owned()), - name: ANNOTATION.to_owned(), - attributes: Default::default(), - nodes: vec![exile::Node::Element(exile::Element { - namespace: Some("xs".to_owned()), - name: DOCUMENTATION.to_owned(), - attributes: Default::default(), - nodes: vec![exile::Node::Text(want_doc.to_owned())], - })], - }; - - let result = Annotation::from_xml(&xml, Lineage::Index(want_index), &Xsd::new("foo")); - assert!(result.is_err()); -} - -#[test] -fn parse_foo_ok() { - let want_index: u64 = 13; - let want_name = "4594507136952412519"; - let want_doc = "bishop is sleeping."; - let xml = exile::Element { - namespace: Some("foo".to_owned()), - name: ANNOTATION.to_owned(), - attributes: Default::default(), - nodes: vec![exile::Node::Element(exile::Element { - namespace: Some("foo".to_owned()), - name: DOCUMENTATION.to_owned(), - attributes: Default::default(), - nodes: vec![exile::Node::Text(want_doc.to_owned())], - })], - }; - - let result = Annotation::from_xml(&xml, Lineage::Index(want_index), &Xsd::new("foo")); - assert!(result.is_ok()); -} diff --git a/gen/version-b/src/xsd/attribute.rs b/gen/version-b/src/xsd/attribute.rs deleted file mode 100644 index a5040e276..000000000 --- a/gen/version-b/src/xsd/attribute.rs +++ /dev/null @@ -1,76 +0,0 @@ -use crate::error::Result; -use crate::xsd::annotation::Annotation; -use crate::xsd::common::DefinedBy; -use crate::xsd::constants::{ANNOTATION, ATTRIBUTE, DEFAULT, FIXED, NAME, REF, TYPE}; -use crate::xsd::id::{Id, Lineage, RootNodeType}; -use crate::xsd::{use_required, Xsd}; - -#[derive(Clone, Debug)] -pub struct Attribute { - pub id: Id, - pub name: String, - pub annotation: Option, - pub defined_by: DefinedBy, - pub required: bool, - pub default: Option, - pub fixed: Option, -} - -impl Attribute { - pub fn documentation(&self) -> String { - if let Some(a) = &self.annotation { - a.documentation() - } else { - "".to_owned() - } - } - - pub fn from_xml(node: &exile::Element, lineage: Lineage, xsd: &Xsd) -> Result { - check!(ATTRIBUTE, node, xsd)?; - let (id, lineage) = Id::make(lineage, node)?; - let name = Self::parse_name(node); - let defined_by = Self::parse_defined_by(node)?; - Ok(Attribute { - id, - name, - annotation: Self::parse_annotation(node, lineage, xsd)?, - required: use_required(node), - defined_by, - default: node.attributes.map().get(DEFAULT).cloned(), - fixed: node.attributes.map().get(FIXED).cloned(), - }) - } - - fn parse_defined_by(node: &exile::Element) -> Result { - if let Some(ref_) = node.attributes.map().get(REF) { - Ok(DefinedBy::Ref(ref_.clone())) - } else if let Some(type_) = node.attributes.map().get(TYPE) { - Ok(DefinedBy::Type(type_.clone())) - } else { - raise!("could not find either '{}' or '{}' attribute", REF, TYPE) - } - } - - fn parse_name(node: &exile::Element) -> String { - if let Some(name) = node.attributes.map().get(NAME) { - name.clone() - } else { - "".to_owned() - } - } - - fn parse_annotation( - node: &exile::Element, - lineage: Lineage, - xsd: &Xsd, - ) -> Result> { - for child in node.children() { - let t = child.name.as_str(); - match t { - ANNOTATION => return Ok(Some(Annotation::from_xml(node, lineage, xsd)?)), - _ => return raise!("unexpected node '{}'", t), - } - } - Ok(None) - } -} diff --git a/gen/version-b/src/xsd/attribute_group.rs b/gen/version-b/src/xsd/attribute_group.rs deleted file mode 100644 index ffecd6dfd..000000000 --- a/gen/version-b/src/xsd/attribute_group.rs +++ /dev/null @@ -1,139 +0,0 @@ -use crate::error::Result; -use crate::xsd::annotation::Annotation; -use crate::xsd::attributes::{add_attributes_from_xml, Attributes}; -use crate::xsd::constants::{ANNOTATION, ATTRIBUTE_GROUP, NAME, REF}; -use crate::xsd::id::{Id, Lineage, RootNodeType}; -use crate::xsd::{name_attribute, ref_attribute, Xsd}; - -#[derive(Clone, Debug)] -pub enum AttributeGroup { - Def(AttributeGroupDef), - Ref(AttributeGroupRef), -} - -#[derive(Clone, Debug)] -pub struct AttributeGroupDef { - pub id: Id, - pub name: String, - pub annotation: Option, - pub attributes: Attributes, -} - -#[derive(Clone, Debug)] -pub struct AttributeGroupRef { - pub id: Id, - pub annotation: Option, - pub ref_: String, -} - -impl AttributeGroup { - pub fn id(&self) -> &Id { - match self { - AttributeGroup::Def(x) => &x.id, - AttributeGroup::Ref(x) => &x.id, - } - } - - pub fn documentation(&self) -> String { - if let AttributeGroup::Def(def) = self { - def.documentation() - } else { - "".to_owned() - } - } - - pub fn from_xml(node: &exile::Element, lineage: Lineage, xsd: &Xsd) -> Result { - check!(ATTRIBUTE_GROUP, node, xsd)?; - let (id, lineage) = Id::make(lineage, node)?; - if let Some(_ref_) = node.attributes.map().get(REF) { - Ok(AttributeGroup::Ref(AttributeGroupRef::from_xml( - node, lineage, xsd, - )?)) - } else { - Ok(AttributeGroup::Def(AttributeGroupDef::from_xml( - node, lineage, xsd, - )?)) - } - } - - pub fn is_ref(&self) -> bool { - match self { - AttributeGroup::Def(_) => false, - AttributeGroup::Ref(_) => true, - } - } - - pub fn is_def(&self) -> bool { - match self { - AttributeGroup::Def(_) => true, - AttributeGroup::Ref(_) => false, - } - } -} - -impl AttributeGroupDef { - pub fn documentation(&self) -> String { - if let Some(a) = &self.annotation { - a.documentation() - } else { - "".to_owned() - } - } - - pub fn from_xml(node: &exile::Element, lineage: Lineage, xsd: &Xsd) -> Result { - let name = name_attribute(node)?; - let id = lineage.parent().unwrap(); - Ok(Self { - id: id.clone(), - name, - annotation: Self::parse_annotation(node, lineage.clone(), xsd)?, - attributes: add_attributes_from_xml(node, lineage.clone(), xsd)?, - }) - } - - fn parse_annotation( - node: &exile::Element, - lineage: Lineage, - xsd: &Xsd, - ) -> Result> { - for inner in node.children() { - if inner.name.as_str() == ANNOTATION { - return Ok(Some(Annotation::from_xml(inner, lineage, xsd)?)); - } - } - Ok(None) - } -} - -impl AttributeGroupRef { - pub fn documentation(&self) -> String { - if let Some(a) = &self.annotation { - a.documentation() - } else { - "".to_owned() - } - } - - pub fn from_xml(node: &exile::Element, lineage: Lineage, xsd: &Xsd) -> Result { - let ref_ = ref_attribute(node)?; - let id = lineage.parent().unwrap(); - Ok(Self { - id: id.clone(), - annotation: Self::parse_annotation(node, lineage.clone(), xsd)?, - ref_, - }) - } - - fn parse_annotation( - node: &exile::Element, - lineage: Lineage, - xsd: &Xsd, - ) -> Result> { - for inner in node.children() { - if inner.name.as_str() == ANNOTATION { - return Ok(Some(Annotation::from_xml(inner, lineage, xsd)?)); - } - } - Ok(None) - } -} diff --git a/gen/version-b/src/xsd/attributes.rs b/gen/version-b/src/xsd/attributes.rs deleted file mode 100644 index 59968133e..000000000 --- a/gen/version-b/src/xsd/attributes.rs +++ /dev/null @@ -1,99 +0,0 @@ -use crate::error::Result; - -use crate::xsd::attribute::Attribute; -use crate::xsd::attribute_group::AttributeGroup; -use crate::xsd::constants::{ANNOTATION, ATTRIBUTE, ATTRIBUTE_GROUP}; -use crate::xsd::id::Lineage; -use crate::xsd::Xsd; - -pub type Attributes = Vec; - -#[derive(Clone, Debug)] -pub enum AttributeItem { - AttributeGroup(AttributeGroup), - Attribute(Attribute), -} - -impl AttributeItem { - pub fn from_xml(node: &exile::Element, lineage: Lineage, xsd: &Xsd) -> Result { - let t = node.name.as_str(); - match t { - ATTRIBUTE => Ok(Self::Attribute(Attribute::from_xml(node, lineage, xsd)?)), - ATTRIBUTE_GROUP => Ok(Self::AttributeGroup(AttributeGroup::from_xml( - node, lineage, xsd, - )?)), - _ => return raise!("unexpected node '{}'", t), - } - } -} - -/// Ignores `parent` but parses each of its children into an AttributeItem. Ignores `annotation` -/// and returns an error if anything else other then `attribute` or `attributeGroup` is found. -pub fn add_attributes_from_xml( - parent: &exile::Element, - lineage: Lineage, - xsd: &Xsd, -) -> Result { - let mut items = Attributes::new(); - for it in parent.children() { - let t = it.name.as_str(); - match t { - ANNOTATION => continue, - _ => items.push(AttributeItem::from_xml(it, lineage.clone(), xsd)?), - } - } - Ok(items) -} - -#[test] -fn parse_attribute_group() { - let parent = crate::xsd::id::Id::new(crate::xsd::id::RootNodeType::Element, "foo".into()); - let xml_str = r#""#; - let doc = exile::parse(xml_str).unwrap(); - let xml = doc.root(); - let result = AttributeItem::from_xml(&xml, Lineage::Parent(parent), &Xsd::new("xs")).unwrap(); - match &result { - AttributeItem::AttributeGroup(x) => assert!(x.is_ref()), - AttributeItem::Attribute(_) => panic!("expected AttributeGroup got Attribute"), - } -} - -#[test] -fn parse_attribute() { - let parent = crate::xsd::id::Id::new(crate::xsd::id::RootNodeType::Element, "foo".into()); - let xml_str = r#""#; - let doc = exile::parse(xml_str).unwrap(); - let xml = doc.root(); - let result = AttributeItem::from_xml(&xml, Lineage::Parent(parent), &Xsd::new("xs")).unwrap(); - match &result { - AttributeItem::AttributeGroup(_) => panic!("expected AttributeGroup got Attribute"), - AttributeItem::Attribute(a) => assert_eq!(a.name, "accelerate"), - } -} - -#[test] -fn attributes() { - let parent = crate::xsd::id::Id::new(crate::xsd::id::RootNodeType::Element, "foo".into()); - let xml_str = r#" - - - Flerubin. - - - - - - "#; - let doc = exile::parse(xml_str).unwrap(); - let xml = doc.root(); - let result = add_attributes_from_xml(&xml, Lineage::Parent(parent), &Xsd::new("xs")).unwrap(); - assert_eq!(result.len(), 4); - match result.get(0).unwrap() { - AttributeItem::AttributeGroup(ag) => assert!(ag.is_ref()), - AttributeItem::Attribute(_) => panic!("wrong variant"), - } - match result.get(1).unwrap() { - AttributeItem::AttributeGroup(_) => panic!("wrong variant"), - AttributeItem::Attribute(a) => assert!(a.defined_by.is_type()), - } -} diff --git a/gen/version-b/src/xsd/choice.rs b/gen/version-b/src/xsd/choice.rs deleted file mode 100644 index 1be6c76a8..000000000 --- a/gen/version-b/src/xsd/choice.rs +++ /dev/null @@ -1,132 +0,0 @@ -use crate::error::Result; -use crate::xsd::annotation::Annotation; -use crate::xsd::constants::{ANNOTATION, CHOICE, ELEMENT, GROUP, NAME, SEQUENCE}; -use crate::xsd::element::Element; -use crate::xsd::group::Group; -use crate::xsd::id::{Id, Lineage, RootNodeType}; -use crate::xsd::sequence::Sequence; -use crate::xsd::Xsd; - -#[derive(Clone, Debug)] -pub struct Choice { - pub id: Id, - pub annotation: Option, - pub choices: Choices, -} - -#[derive(Clone, Debug)] -pub enum ChoiceItem { - Element(Element), - Group(Group), - Sequence(Sequence), -} - -pub type Choices = Vec; - -impl Choice { - pub fn documentation(&self) -> String { - if let Some(annotation) = &self.annotation { - return annotation.documentation(); - } - return "".to_owned(); - } - - pub fn from_xml(node: &exile::Element, lineage: Lineage, xsd: &Xsd) -> Result { - check!(CHOICE, node, xsd)?; - let (id, lineage) = Id::make(lineage, node)?; - let mut annotation = None; - let mut choices = Choices::new(); - for inner in node.children() { - let t = inner.name.as_str(); - match t { - ANNOTATION => annotation = Some(Annotation::from_xml(inner, lineage.clone(), xsd)?), - ELEMENT => choices.push(ChoiceItem::Element(Element::from_xml( - inner, - lineage.clone(), - xsd, - )?)), - GROUP => choices.push(ChoiceItem::Group(Group::from_xml( - inner, - lineage.clone(), - xsd, - )?)), - SEQUENCE => choices.push(ChoiceItem::Sequence(Sequence::from_xml( - inner, - lineage.clone(), - xsd, - )?)), - _ => return raise!("cannot parse '{}', unexpected node '{}'", CHOICE, t), - } - } - Ok(Choice { - id, - annotation, - choices, - }) - } -} -/* - - - - - - - - - - - -*/ - -/* - - - - - - - - The optional list of key-octave elements is used to specify in which octave each element of the key signature appears. - - - -*/ -#[test] -fn parse_credit() { - let parent = crate::xsd::id::Id::new(crate::xsd::id::RootNodeType::Element, "foo".into()); - let xml_str = r#" - - - - - - - - - - - "#; - let doc = exile::parse(xml_str).unwrap(); - let xml = doc.root(); - let ch = Choice::from_xml(&xml, Lineage::Parent(parent), &Xsd::new("xs")).unwrap(); - assert_eq!( - format!("{}", ch.id), - "element:foo:choice:863778347360799337" - ); - assert_eq!(ch.documentation().as_str(), ""); - assert_eq!(ch.choices.len(), 2); - let ele = if let ChoiceItem::Element(el) = ch.choices.get(0).unwrap() { - el - } else { - panic!("expected Element"); - }; - assert_eq!(ele.name(), "credit-image"); - let seq = if let ChoiceItem::Sequence(s) = ch.choices.get(1).unwrap() { - s - } else { - panic!("expected Sequence"); - }; - assert_eq!(seq.occurs.min_occurs, 1); - assert_eq!(seq.occurs.max_occurs, Some(1)); -} diff --git a/gen/version-b/src/xsd/common.rs b/gen/version-b/src/xsd/common.rs deleted file mode 100644 index e96591487..000000000 --- a/gen/version-b/src/xsd/common.rs +++ /dev/null @@ -1,56 +0,0 @@ -use std::fmt::{Display, Formatter}; - -#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug)] -pub enum DefinedBy { - Ref(String), - Type(String), -} - -impl DefinedBy { - /// A quicker way, if you don't care whether it is a Ref or a Def - pub fn value(&self) -> &str { - match self { - DefinedBy::Ref(s) => s.as_str(), - DefinedBy::Type(s) => s.as_str(), - } - } - - pub fn is_ref(&self) -> bool { - match self { - DefinedBy::Ref(_) => true, - _ => false, - } - } - - pub fn is_type(&self) -> bool { - match self { - DefinedBy::Type(_) => true, - _ => false, - } - } -} - -impl Display for DefinedBy { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - match self { - DefinedBy::Ref(s) => write!(f, "ref:{}", s), - DefinedBy::Type(s) => write!(f, "type:{}", s), - } - } -} - -#[test] -fn defined_by_tests() { - let t = DefinedBy::Type("x".into()); - assert!(t.is_type()); - assert!(!t.is_ref()); - assert_eq!(t.value(), "x"); - let r = DefinedBy::Ref("y".into()); - assert!(!r.is_type()); - assert!(r.is_ref()); - assert_eq!(r.value(), "y"); - let ts = format!("{}", &t); - assert_eq!("type:x", ts.as_str()); - let rs = format!("{}", &r); - assert_eq!("ref:y", rs.as_str()); -} diff --git a/gen/version-b/src/xsd/complex_content.rs b/gen/version-b/src/xsd/complex_content.rs deleted file mode 100644 index 1313f4247..000000000 --- a/gen/version-b/src/xsd/complex_content.rs +++ /dev/null @@ -1,88 +0,0 @@ -use crate::error::Result; -use crate::xsd::annotation::Annotation; -use crate::xsd::constants::{ANNOTATION, COMPLEX_CONTENT, EXTENSION, NAME}; -use crate::xsd::extension::Extension; -use crate::xsd::id::{Id, Lineage, RootNodeType}; -use crate::xsd::Xsd; - -#[derive(Clone, Debug)] -pub struct ComplexContent { - pub id: Id, - pub annotation: Option, - pub extension: Extension, -} - -impl ComplexContent { - pub fn documentation(&self) -> String { - if let Some(annotation) = &self.annotation { - return annotation.documentation(); - } - return "".to_owned(); - } - - pub fn from_xml(node: &exile::Element, lineage: Lineage, xsd: &Xsd) -> Result { - check!(COMPLEX_CONTENT, node, xsd)?; - let (id, lineage) = Id::make(lineage, node)?; - let mut annotation = None; - let mut extension = None; - for inner in node.children() { - let t = inner.name.as_str(); - match t { - ANNOTATION => annotation = Some(Annotation::from_xml(inner, lineage.clone(), xsd)?), - EXTENSION => { - extension = Some(Extension::from_xml(inner, lineage.clone(), xsd)?); - } - _ => return raise!("unsupported simpleContent node '{}'", t), - } - } - let extension = if let Some(ext) = extension { - ext - } else { - return raise!("{} payload was not found", COMPLEX_CONTENT); - }; - Ok(ComplexContent { - id, - annotation, - extension, - }) - } -} - -#[test] -fn parse() { - use super::attributes::AttributeItem; - let parent = crate::xsd::id::Id::new(crate::xsd::id::RootNodeType::Element, "foo".into()); - let lineage = Lineage::Parent(parent); - let xml_str = r#" - - - - - - - "#; - let doc = exile::parse(xml_str).unwrap(); - let xml = doc.root(); - let want_id = "element:foo:complexContent:10793997753492324063".to_owned(); - let want_doc = ""; - let sc = ComplexContent::from_xml(&xml, lineage, &Xsd::new("xs")).unwrap(); - let got_doc = sc.documentation(); - assert_eq!(got_doc.as_str(), want_doc); - let got_id = format!("{}", sc.id); - assert_eq!(got_id, want_id); - // let got_type = sc.id.entry_type; - // assert_eq!(got_type, RootNodeType::Other(COMPLEX_CONTENT.to_owned())); - let extension = &sc.extension; - assert_eq!(extension.base.as_str(), "time-modification"); - assert_eq!(extension.attributes.len(), 3); - let a = extension.attributes.get(0).unwrap(); - match a { - AttributeItem::Attribute(x) => { - assert_eq!(x.name.as_str(), "type"); - assert!(x.defined_by.is_type()); - assert_eq!(x.defined_by.value(), "start-stop"); - assert!(x.required); - } - AttributeItem::AttributeGroup(_) => panic!("expected 'Attribute' but got 'AttributeGroup'"), - } -} diff --git a/gen/version-b/src/xsd/complex_type.rs b/gen/version-b/src/xsd/complex_type.rs deleted file mode 100644 index a9351d19d..000000000 --- a/gen/version-b/src/xsd/complex_type.rs +++ /dev/null @@ -1,359 +0,0 @@ -use crate::error::Result; -use crate::xsd::annotation::Annotation; -use crate::xsd::attributes::{AttributeItem, Attributes}; -use crate::xsd::choice::Choice; -use crate::xsd::complex_content::ComplexContent; -use crate::xsd::constants::{ - ANNOTATION, ATTRIBUTE, ATTRIBUTE_GROUP, CHOICE, COMPLEX_CONTENT, COMPLEX_TYPE, GROUP, NAME, - SEQUENCE, SIMPLE_CONTENT, -}; -use crate::xsd::group::Group; -use crate::xsd::id::{Id, Lineage, RootNodeId, RootNodeType}; -use crate::xsd::sequence::Sequence; -use crate::xsd::simple_content::SimpleContent; -use crate::xsd::Xsd; - -#[derive(Clone, Debug)] -pub struct ComplexType { - pub id: Id, - pub name: String, - pub annotation: Option, - pub payload: Payload, -} - -#[derive(Clone, Debug)] -pub enum Payload { - ComplexContent(ComplexContent), - SimpleContent(SimpleContent), - Parent(Parent), - None, -} - -#[derive(Clone, Debug)] -pub enum Children { - Choice(Choice), - Group(Group), - Sequence(Sequence), -} - -#[derive(Clone, Debug)] -pub struct Parent { - pub attributes: Attributes, - pub children: Option, -} - -impl ComplexType { - pub fn documentation(&self) -> String { - if let Some(annotation) = &self.annotation { - return annotation.documentation(); - } - return "".to_owned(); - } - - pub fn from_xml(node: &exile::Element, lineage: Lineage, xsd: &Xsd) -> Result { - check!(COMPLEX_TYPE, node, xsd)?; - let (id, lineage) = Id::make(lineage, node)?; - let mut annotation = None; - let mut payload = Payload::None; - for inner in node.children() { - let t = inner.name.as_str(); - match t { - ANNOTATION => annotation = Some(Annotation::from_xml(inner, lineage.clone(), xsd)?), - CHOICE | GROUP | SEQUENCE => { - payload = Payload::Parent(Parent::from_xml(node, lineage.clone(), xsd)?); - break; - } - COMPLEX_CONTENT => { - payload = Payload::ComplexContent(ComplexContent::from_xml( - inner, - lineage.clone(), - xsd, - )?) - } - SIMPLE_CONTENT => { - payload = Payload::SimpleContent(SimpleContent::from_xml( - inner, - lineage.clone(), - xsd, - )?) - } - ATTRIBUTE | ATTRIBUTE_GROUP => { /* will be parsed by Parent::from_xml() */ } - _ => return raise!("unexpected node '{}' while parsing complexType", t), - } - } - let name = if let Some(n) = node.attributes.map().get(NAME) { - n.clone() - } else { - "".to_owned() - }; - Ok(ComplexType { - id, - name, - annotation, - payload, - }) - } -} - -impl Parent { - pub fn from_xml(node: &exile::Element, lineage: Lineage, xsd: &Xsd) -> Result { - let mut parent = Parent { - attributes: vec![], - children: None, - }; - for inner in node.children() { - let t = inner.name.as_str(); - match t { - CHOICE => { - parent.children = Some(Children::Choice(Choice::from_xml( - inner, - lineage.clone(), - xsd, - )?)); - } - GROUP => { - parent.children = Some(Children::Group(Group::from_xml( - inner, - lineage.clone(), - xsd, - )?)); - } - SEQUENCE => { - parent.children = Some(Children::Sequence(Sequence::from_xml( - inner, - lineage.clone(), - xsd, - )?)); - } - ATTRIBUTE | ATTRIBUTE_GROUP => { - parent - .attributes - .push(AttributeItem::from_xml(inner, lineage.clone(), xsd)?) - } - ANNOTATION => { /* ignore because it's parsed by ComplexType::from_xml */ } - _ => return raise!("unable to parse complexType, unexpected node '{}'", t), - } - } - Ok(parent) - } -} - -#[test] -fn parse_parent_sequence() { - use crate::xsd::attribute_group::AttributeGroup; - let xml_str = r#" - - - - - - - - - - - - - - - - - - - "#; - let doc = exile::parse(xml_str).unwrap(); - let xml = doc.root(); - let want_index: u64 = 6; - let ct = ComplexType::from_xml(&xml, Lineage::Index(want_index), &Xsd::new("xs")).unwrap(); - assert_eq!(format!("{}", ct.id), "complexType:14524941899531583637"); - assert_eq!(ct.documentation().as_str(), ""); - let parent = if let Payload::Parent(p) = ct.payload { - p - } else { - panic!("wrong payload type"); - }; - assert_eq!(parent.attributes.len(), 1); - match parent.attributes.get(0).unwrap() { - AttributeItem::AttributeGroup(ag) => match ag { - AttributeGroup::Def(_) => panic!("expected Ref got Def"), - AttributeGroup::Ref(s) => { - assert_eq!(s.ref_.as_str(), "document-attributes"); - } - }, - AttributeItem::Attribute(_) => panic!("expected AttributeGroup got Attribute"), - } - match parent.children.unwrap() { - Children::Choice(_) => panic!("want Sequence got Choice"), - Children::Group(_) => panic!("want Sequence got Group"), - Children::Sequence(_) => {} - } -} - -#[test] -fn parse_parent_group() { - let xml_str = r#" - - - System margins are relative to the page margins. - - - "#; - let doc = exile::parse(xml_str).unwrap(); - let xml = doc.root(); - let want_index: u64 = 6; - let ct = ComplexType::from_xml(&xml, Lineage::Index(want_index), &Xsd::new("xs")).unwrap(); - assert_eq!(format!("{}", ct.id), "complexType:system-margins"); - assert_eq!( - ct.documentation().as_str(), - "System margins are relative to the page margins." - ); - let parent = if let Payload::Parent(p) = ct.payload { - p - } else { - panic!("wrong payload type"); - }; - assert_eq!(parent.attributes.len(), 0); - match parent.children.unwrap() { - Children::Choice(_) => panic!("want Group got Choice"), - Children::Group(_) => {} - Children::Sequence(_) => panic!("want Group got Sequence"), - } -} - -#[test] -fn parse_parent_choice() { - use crate::xsd::attribute_group::AttributeGroup; - let xml_str = r#" - - - The arrow element represents an arrow. - - - - - - - - - - - "#; - let doc = exile::parse(xml_str).unwrap(); - let xml = doc.root(); - let want_index: u64 = 6; - let ct = ComplexType::from_xml(&xml, Lineage::Index(want_index), &Xsd::new("xs")).unwrap(); - assert_eq!(format!("{}", ct.id), "complexType:arrow"); - assert_eq!( - ct.documentation().as_str(), - "The arrow element represents an arrow." - ); - let parent = if let Payload::Parent(p) = ct.payload { - p - } else { - panic!("wrong payload type"); - }; - assert_eq!(parent.attributes.len(), 2); - match parent.attributes.get(0).unwrap() { - AttributeItem::AttributeGroup(ag) => match ag { - AttributeGroup::Def(_) => panic!("expected Ref got Def"), - AttributeGroup::Ref(s) => { - assert_eq!(s.ref_.as_str(), "print-style"); - } - }, - AttributeItem::Attribute(_) => panic!("expected AttributeGroup got Attribute"), - } - match parent.attributes.get(1).unwrap() { - AttributeItem::AttributeGroup(ag) => match ag { - AttributeGroup::Def(_) => panic!("expected Ref got Def"), - AttributeGroup::Ref(s) => { - assert_eq!(s.ref_.as_str(), "placement"); - } - }, - AttributeItem::Attribute(_) => panic!("expected AttributeGroup got Attribute"), - } - match parent.children.unwrap() { - Children::Choice(_) => {} - Children::Group(_) => panic!("want Choice got Group"), - Children::Sequence(_) => panic!("want Choice got Sequence"), - } -} - -#[test] -fn parse_complex_content() { - let xml_str = r#" - - - Heel and toe elements are used with organ pedals. - - - - - - - "#; - let doc = exile::parse(xml_str).unwrap(); - let xml = doc.root(); - let want_index: u64 = 6; - let ct = ComplexType::from_xml(&xml, Lineage::Index(want_index), &Xsd::new("xs")).unwrap(); - assert_eq!(format!("{}", ct.id), "complexType:heel-toe"); - assert_eq!( - ct.documentation().as_str(), - "Heel and toe elements are used with organ pedals." - ); - let cc = if let Payload::ComplexContent(cc) = ct.payload { - cc - } else { - panic!("wrong payload type"); - }; - assert_eq!(cc.extension.attributes.len(), 1); - match cc.extension.attributes.get(0).unwrap() { - AttributeItem::Attribute(a) => { - assert_eq!(a.name.as_str(), "substitution"); - assert!(a.defined_by.is_type()); - assert_eq!(a.defined_by.value(), "yes-no"); - } - AttributeItem::AttributeGroup(_) => panic!("expected Attribute got AttributeGroup"), - } -} - -#[test] -fn parse_simple_content() { - use super::simple_content; - let xml_str = r#" - - - The hole-closed type represents whether the... - - - - - - - "#; - let doc = exile::parse(xml_str).unwrap(); - let xml = doc.root(); - let want_index: u64 = 6; - let ct = ComplexType::from_xml(&xml, Lineage::Index(want_index), &Xsd::new("xs")).unwrap(); - assert_eq!(format!("{}", ct.id), "complexType:hole-closed"); - assert_eq!( - ct.documentation().as_str(), - "The hole-closed type represents whether the..." - ); - let sc = if let Payload::SimpleContent(sc) = ct.payload { - sc - } else { - panic!("wrong payload type"); - }; - let ext = match &sc.payload { - simple_content::Payload::Extension(x) => x, - }; - assert_eq!(ext.base.as_str(), "hole-closed-value"); - assert_eq!(ext.attributes.len(), 1); - match ext.attributes.get(0).unwrap() { - AttributeItem::AttributeGroup(_) => panic!("expected Attribute got AttributeGroup"), - AttributeItem::Attribute(a) => { - assert!(a.defined_by.is_type()); - assert_eq!(a.defined_by.value(), "hole-closed-location"); - } - } -} diff --git a/gen/version-b/src/xsd/constants.rs b/gen/version-b/src/xsd/constants.rs deleted file mode 100644 index 937d5dd12..000000000 --- a/gen/version-b/src/xsd/constants.rs +++ /dev/null @@ -1,72 +0,0 @@ -pub const ANNOTATION: &str = "annotation"; -pub const APP_INFO: &str = "appinfo"; -pub const ATTRIBUTE: &str = "attribute"; -pub const ATTRIBUTE_GROUP: &str = "attributeGroup"; -pub const BASE: &str = "base"; -pub const BYTE: &str = "byte"; -pub const CHOICE: &str = "choice"; -pub const COMPLEX_CONTENT: &str = "complexContent"; -pub const COMPLEX_TYPE: &str = "complexType"; -pub const DATE: &str = "date"; -pub const DATETIME: &str = "dateTime"; -pub const DECIMAL: &str = "decimal"; -pub const DEFAULT: &str = "default"; -pub const DOCUMENTATION: &str = "documentation"; -pub const DURATION: &str = "duration"; -pub const ELEMENT: &str = "element"; -pub const ENUMERATION: &str = "enumeration"; -pub const EXTENSION: &str = "extension"; -pub const FIXED: &str = "fixed"; -pub const G_DAY: &str = "gDay"; -pub const G_MONTH: &str = "gMonth"; -pub const G_MONTH_DAY: &str = "gMonthDay"; -pub const G_YEAR: &str = "gYear"; -pub const G_YEAR_MONTH: &str = "gYearMonth"; -pub const GROUP: &str = "group"; -pub const ID: &str = "ID"; -pub const IDREF: &str = "IDREF"; -pub const IMPORT: &str = "import"; -pub const INT: &str = "int"; -pub const INTEGER: &str = "integer"; -pub const LANGUAGE: &str = "language"; -pub const LENGTH: &str = "length"; -pub const LIST: &str = "list"; -pub const LONG: &str = "long"; -pub const MAX_EXCLUSIVE: &str = "maxExclusive"; -pub const MAX_INCLUSIVE: &str = "maxInclusive"; -pub const MAX_LENGTH: &str = "maxLength"; -pub const MAX_OCCURS: &str = "maxOccurs"; -pub const MEMBER_TYPES: &str = "memberTypes"; -pub const MIN_EXCLUSIVE: &str = "minExclusive"; -pub const MIN_INCLUSIVE: &str = "minInclusive"; -pub const MIN_LENGTH: &str = "minLength"; -pub const MIN_OCCURS: &str = "minOccurs"; -pub const NAME: &str = "name"; -pub const NAMESPACE: &str = "namespace"; -pub const NEGATIVE_INTEGER: &str = "negativeInteger"; -pub const NMTOKEN: &str = "NMTOKEN"; -pub const NON_NEGATIVE_INTEGER: &str = "nonNegativeInteger"; -pub const NON_POSITIVE_INTEGER: &str = "nonPositiveInteger"; -pub const NORMALIZED_STRING: &str = "normalizedString"; -pub const PATTERN: &str = "pattern"; -pub const POSITIVE_INTEGER: &str = "positiveInteger"; -pub const REF: &str = "ref"; -pub const REQUIRED: &str = "required"; -pub const RESTRICTION: &str = "restriction"; -pub const SCHEMA_LOCATION: &str = "schemaLocation"; -pub const SEQUENCE: &str = "sequence"; -pub const SHORT: &str = "short"; -pub const SIMPLE_CONTENT: &str = "simpleContent"; -pub const SIMPLE_TYPE: &str = "simpleType"; -pub const STRING: &str = "string"; -pub const TIME: &str = "time"; -pub const TOKEN: &str = "token"; -pub const TYPE: &str = "type"; -pub const UNBOUNDED: &str = "unbounded"; -pub const UNION: &str = "union"; -pub const UNSIGNED_BYTE: &str = "unsignedByte"; -pub const UNSIGNED_INT: &str = "unsignedInt"; -pub const UNSIGNED_LONG: &str = "unsignedLong"; -pub const UNSIGNED_SHORT: &str = "unsignedShort"; -pub const USE: &str = "use"; -pub const VALUE: &str = "value"; diff --git a/gen/version-b/src/xsd/element.rs b/gen/version-b/src/xsd/element.rs deleted file mode 100644 index 74c851ec8..000000000 --- a/gen/version-b/src/xsd/element.rs +++ /dev/null @@ -1,244 +0,0 @@ -use crate::error::Result; -use crate::xsd::annotation::Annotation; -use crate::xsd::complex_type::ComplexType; -use crate::xsd::constants::{ANNOTATION, COMPLEX_TYPE, ELEMENT, NAME, TYPE}; -use crate::xsd::id::{Id, Lineage, RootNodeType}; -use crate::xsd::primitives::{BaseType, PrefixedParse, PrefixedString}; -use crate::xsd::{name_attribute, type_attribute, Occurs, Xsd}; - -#[derive(Clone, Debug)] -pub enum Element { - Definition(ElementDef), - Reference(ElementRef), -} - -impl Element { - pub fn documentation(&self) -> String { - match self { - Element::Definition(x) => { - if let Some(annotation) = &x.annotation { - return annotation.documentation(); - } - } - Element::Reference(x) => { - if let Some(annotation) = &x.annotation { - return annotation.documentation(); - } - } - } - return "".to_owned(); - } - - pub fn id(&self) -> &Id { - match self { - Element::Definition(x) => &x.id, - Element::Reference(x) => &x.id, - } - } - - pub fn name(&self) -> &str { - match self { - Element::Definition(d) => d.name.as_str(), - Element::Reference(r) => r.name.as_str(), - } - } - - pub fn occurs(&self) -> &Occurs { - match self { - Element::Definition(d) => &d.occurs, - Element::Reference(r) => &r.occurs, - } - } - - pub fn from_xml(node: &exile::Element, lineage: Lineage, xsd: &Xsd) -> Result { - let (id, lineage) = Id::make(lineage, node)?; - if let Some(_) = node.attributes.map().get(TYPE) { - Ok(Element::Reference(ElementRef::from_xml( - node, lineage, xsd, - )?)) - } else { - Ok(Element::Definition(ElementDef::from_xml( - node, lineage, xsd, - )?)) - } - } -} - -#[derive(Clone, Debug)] -pub struct ElementDef { - pub id: Id, - pub annotation: Option, - pub name: String, - pub occurs: Occurs, - pub complex_type: ComplexType, -} - -impl ElementDef { - pub fn documentation(&self) -> String { - if let Some(annotation) = &self.annotation { - return annotation.documentation(); - } - return "".to_owned(); - } - - pub fn from_xml(node: &exile::Element, lineage: Lineage, xsd: &Xsd) -> Result { - check!(ELEMENT, node, xsd)?; - let id = lineage.parent().unwrap(); - let mut annotation = None; - let mut complex_type = None; - for inner in node.children() { - let t = inner.name.as_str(); - match t { - ANNOTATION => annotation = Some(Annotation::from_xml(inner, lineage.clone(), xsd)?), - COMPLEX_TYPE => { - complex_type = Some(ComplexType::from_xml(inner, lineage.clone(), xsd)?) - } - _ => return raise!("unsupported inner type: '{}'", t), - } - } - let complex_type = if let Some(x) = complex_type { - x - } else { - return raise!("{} not found!", COMPLEX_TYPE); - }; - let name = name_attribute(node)?; - Ok(ElementDef { - id: id.clone(), - annotation, - name, - occurs: Occurs::from_xml(node)?, - complex_type, - }) - } -} - -#[derive(Clone, Debug)] -pub struct ElementRef { - pub id: Id, - pub annotation: Option, - pub name: String, - pub type_: BaseType, - pub occurs: Occurs, -} - -impl ElementRef { - pub fn documentation(&self) -> String { - if let Some(annotation) = &self.annotation { - return annotation.documentation(); - } - return "".to_owned(); - } - - pub fn from_xml(node: &exile::Element, lineage: Lineage, xsd: &Xsd) -> Result { - if node.name.as_str() != ELEMENT { - return raise!("expected '{}', got '{}'", ELEMENT, node.name.as_str()); - } - let id = lineage.parent().unwrap(); - let mut annotation = None; - for inner in node.children() { - let t = inner.name.as_str(); - if t == ANNOTATION { - annotation = Some(Annotation::from_xml(inner, lineage.clone(), xsd)?); - break; - } - } - let name = name_attribute(node)?; - Ok(ElementRef { - id: id.clone(), - annotation, - name, - type_: BaseType::parse_prefixed(type_attribute(node)?, xsd.prefix.as_str())?, - occurs: Occurs::from_xml(node)?, - }) - } -} - -#[test] -fn parse_score_partwise() { - use crate::xsd::complex_type::{Children, Payload}; - let xml_str = r#" - - - bleep bleep bloop bloop - - - - - - - - - - - - - - - - - - - - - "#; - let doc = exile::parse(xml_str).unwrap(); - let xml = doc.root(); - let want_index: u64 = 3; - let ele = Element::from_xml(&xml, Lineage::Index(want_index), &Xsd::new("xs")).unwrap(); - let got_id = format!("{}", ele.id()); - let want_id = "element:score-partwise"; - assert_eq!(got_id.as_str(), want_id); - let got_doc = ele.documentation(); - let want_doc = "bleep bleep bloop bloop"; - assert_eq!(got_doc, want_doc); - let ele = match ele { - Element::Definition(x) => x, - Element::Reference(_) => panic!("expected Definition, got Reference"), - }; - assert_eq!( - ele.occurs, - Occurs { - min_occurs: 1, - max_occurs: Some(1), - } - ); - match ele.complex_type.payload { - Payload::ComplexContent(_) => panic!("want Parent got ComplexContent"), - Payload::SimpleContent(_) => panic!("want Parent got SimpleContent"), - Payload::Parent(p) => match &p.children.unwrap() { - Children::Choice(_) => panic!("want Sequence got Choice"), - Children::Group(_) => panic!("want Sequence got Group"), - Children::Sequence(_) => {} - }, - Payload::None => panic!("want Parent got None"), - } -} - -#[test] -fn parse_credit() { - let xml_str = - r#""#; - let doc = exile::parse(xml_str).unwrap(); - let xml = doc.root(); - let want_index: u64 = 6; - let ele = Element::from_xml(&xml, Lineage::Index(want_index), &Xsd::new("xs")).unwrap(); - let got_id = format!("{}", ele.id()); - let want_id = "element:credit"; - assert_eq!(got_id.as_str(), want_id); - let got_doc = ele.documentation(); - let want_doc = ""; - assert_eq!(got_doc, want_doc); - let ele = match ele { - Element::Definition(_) => panic!("expected Reference, got Definition"), - Element::Reference(x) => x, - }; - assert_eq!(ele.name.as_str(), "credit"); - assert_eq!(ele.type_, BaseType::Custom("credit".to_owned())); - assert_eq!( - ele.occurs, - Occurs { - min_occurs: 0, - max_occurs: None, - } - ); -} diff --git a/gen/version-b/src/xsd/extension.rs b/gen/version-b/src/xsd/extension.rs deleted file mode 100644 index c7bb3544c..000000000 --- a/gen/version-b/src/xsd/extension.rs +++ /dev/null @@ -1,98 +0,0 @@ -use crate::error::Result; -use crate::xsd::annotation::Annotation; -use crate::xsd::attributes::{AttributeItem, Attributes}; -use crate::xsd::constants::{ANNOTATION, ATTRIBUTE, ATTRIBUTE_GROUP, EXTENSION, NAME}; -use crate::xsd::id::{Id, Lineage, RootNodeType}; -use crate::xsd::{base_attribute, Xsd}; - -#[derive(Clone, Debug)] -pub struct Extension { - pub id: Id, - pub annotation: Option, - pub base: String, - pub attributes: Attributes, -} - -impl Extension { - pub fn documentation(&self) -> String { - if let Some(annotation) = &self.annotation { - return annotation.documentation(); - } - return "".to_owned(); - } - - pub fn from_xml(node: &exile::Element, lineage: Lineage, xsd: &Xsd) -> Result { - check!(EXTENSION, node, xsd)?; - let (id, lineage) = Id::make(lineage, node)?; - let base = base_attribute(node)?; - let mut annotation = None; - let mut attributes = Attributes::new(); - for inner in node.children() { - let t = inner.name.as_str(); - match t { - ANNOTATION => annotation = Some(Annotation::from_xml(inner, lineage.clone(), xsd)?), - ATTRIBUTE | ATTRIBUTE_GROUP => { - attributes.push(AttributeItem::from_xml(inner, lineage.clone(), xsd)?); - } - _ => return raise!("unsupported {} member '{}'", EXTENSION, t), - } - } - Ok(Extension { - id, - annotation, - base, - attributes, - }) - } -} - -#[test] -fn parse() { - use super::attribute_group::AttributeGroup; - use super::common::DefinedBy; - let parent = crate::xsd::id::Id::new(crate::xsd::id::RootNodeType::Element, "foo".into()); - let lineage = Lineage::Parent(parent); - let xml_str = r#" - - - - - "#; - let doc = exile::parse(xml_str).unwrap(); - let xml = doc.root(); - let want_id = "element:foo:extension:2676136846689128820".to_owned(); - let want_doc = ""; - let ext = Extension::from_xml(&xml, lineage, &Xsd::new("xs")).unwrap(); - let got_doc = ext.documentation(); - assert_eq!(got_doc.as_str(), want_doc); - let got_id = format!("{}", ext.id); - assert_eq!(got_id, want_id); - // let got_type = ext.id.entry_type; - // assert_eq!(got_type, RootNodeType::Other(EXTENSION.to_owned())); - let got_base = ext.base.as_str(); - let want_base = "xs:string"; - assert_eq!(got_base, want_base); - assert_eq!(ext.attributes.len(), 3); - let attribute_item = ext.attributes.get(0).unwrap(); - match attribute_item { - AttributeItem::Attribute(x) => { - assert_eq!(x.name.as_str(), "type"); - match &x.defined_by { - DefinedBy::Ref(_) => panic!("expected Type got Ref"), - DefinedBy::Type(t) => assert_eq!(t, "start-stop"), - } - assert!(x.required); - } - AttributeItem::AttributeGroup(_) => panic!("expected 'Attribute' but got 'AttributeGroup'"), - } - let attribute_item = ext.attributes.get(2).unwrap(); - match attribute_item { - AttributeItem::Attribute(_) => panic!("expected 'AttributeGroup' but got 'Attribute'"), - AttributeItem::AttributeGroup(x) => match x { - AttributeGroup::Def(_) => panic!("expected 'Ref' but got 'Def'"), - AttributeGroup::Ref(r) => { - assert_eq!(r.ref_.as_str(), "print-style-align"); - } - }, - } -} diff --git a/gen/version-b/src/xsd/group.rs b/gen/version-b/src/xsd/group.rs deleted file mode 100644 index 603086205..000000000 --- a/gen/version-b/src/xsd/group.rs +++ /dev/null @@ -1,217 +0,0 @@ -use crate::error::Result; -use crate::xsd::annotation::Annotation; -use crate::xsd::choice::Choice; -use crate::xsd::constants::{ANNOTATION, CHOICE, ELEMENT, GROUP, SEQUENCE}; -use crate::xsd::element::Element; -use crate::xsd::id::{Id, Lineage, RootNodeType}; -use crate::xsd::sequence::Sequence; -use crate::xsd::{is_ref, name_attribute, ref_attribute, Occurs, Xsd}; - -#[derive(Clone, Debug)] -pub enum Group { - Definition(GroupDefinition), - Reference(GroupReference), -} - -impl Group { - pub fn from_xml(node: &exile::Element, lineage: Lineage, xsd: &Xsd) -> Result { - let (id, lineage) = Id::make(lineage, node)?; - if is_ref(node) { - Ok(Group::Reference(GroupReference::from_xml( - node, lineage, xsd, - )?)) - } else { - Ok(Group::Definition(GroupDefinition::from_xml( - node, lineage, xsd, - )?)) - } - } -} - -#[derive(Clone, Debug)] -pub struct GroupDefinition { - pub id: Id, - pub annotation: Option, - pub members: Vec, -} - -#[derive(Clone, Debug)] -pub struct GroupReference { - pub id: Id, - pub annotation: Option, - pub ref_: String, - pub occurs: Occurs, -} - -#[derive(Clone, Debug)] -pub enum Member { - Choice(Choice), - Element(Element), - Sequence(Sequence), -} - -impl GroupDefinition { - pub fn documentation(&self) -> String { - if let Some(annotation) = &self.annotation { - return annotation.documentation(); - } - return "".to_owned(); - } - - pub fn from_xml(node: &exile::Element, lineage: Lineage, xsd: &Xsd) -> Result { - check!(GROUP, node, xsd)?; - // way funky: The first match arm happens if it is a top-level root entry, otherwise the - // caller has already created an ID for this and the second match arm is in effect. - let (id, lineage) = match lineage { - Lineage::Index(i) => Id::make(Lineage::Index(i), node)?, - Lineage::Parent(p) => (p.clone(), Lineage::Parent(p.clone())), - }; - let mut annotation = None; - let mut members = Vec::new(); - for inner in node.children() { - let t = inner.name.as_str(); - match t { - ANNOTATION => annotation = Some(Annotation::from_xml(inner, lineage.clone(), xsd)?), - CHOICE => { - let choice = Choice::from_xml(inner, lineage.clone(), xsd)?; - members.push(Member::Choice(choice)); - } - ELEMENT => { - let element = Element::from_xml(inner, lineage.clone(), xsd)?; - members.push(Member::Element(element)); - } - SEQUENCE => { - let sequence = Sequence::from_xml(inner, lineage.clone(), xsd)?; - members.push(Member::Sequence(sequence)); - } - _ => return raise!("unsupported {} node, '{}'", GROUP, t), - } - } - Ok(GroupDefinition { - id, - annotation, - members, - }) - } -} - -impl GroupReference { - pub fn documentation(&self) -> String { - if let Some(annotation) = &self.annotation { - return annotation.documentation(); - } - return "".to_owned(); - } - - pub fn from_xml(node: &exile::Element, lineage: Lineage, xsd: &Xsd) -> Result { - let id = lineage.parent().unwrap(); - if node.name.as_str() != GROUP { - return raise!("expected '{}', got '{}'", GROUP, node.name.as_str()); - } - let mut annotation = None; - for inner in node.children() { - let t = inner.name.as_str(); - match t { - ANNOTATION => annotation = Some(Annotation::from_xml(inner, lineage.clone(), xsd)?), - _ => return raise!("unsupported {} node, '{}'", GROUP, t), - } - } - let ref_ = ref_attribute(node)?; - Ok(GroupReference { - id: id.clone(), - annotation, - ref_, - occurs: Occurs::from_xml(node)?, - }) - } -} - -#[test] -fn parse_group_definition() { - let xml_str = r#" - - - blerp bloop bleep blop - - - - - - - mervin flervin - - - - - - - - - "#; - let doc = exile::parse(xml_str).unwrap(); - let xml = doc.root(); - let want_index: u64 = 3; - let grp = Group::from_xml(&xml, Lineage::Index(want_index), &Xsd::new("xs")).unwrap(); - let grp = match grp { - Group::Definition(def) => def, - Group::Reference(_) => panic!("expected Definition, got Reference"), - }; - assert_eq!(grp.id.index().unwrap(), want_index); - let got_id = grp.id.to_string(); - let want_id = "group:harmony-chord".to_owned(); - assert_eq!(got_id, want_id); - let got_doc = grp.documentation(); - let want_doc = "blerp bloop bleep blop"; - assert_eq!(got_doc, want_doc); - assert_eq!(grp.members.len(), 1); - let seq = grp.members.get(0).unwrap(); - match seq { - Member::Choice(_) => panic!("expected Sequence, got Choice"), - Member::Element(_) => panic!("expected Sequence, got Element"), - Member::Sequence(s) => s, - }; -} - -#[test] -fn parse_group_reference() { - let xml_str = r#""#; - let doc = exile::parse(xml_str).unwrap(); - let xml = doc.root(); - let want_index: u64 = 3; - let grp = Group::from_xml(&xml, Lineage::Index(want_index), &Xsd::new("xs")).unwrap(); - let grp = match grp { - Group::Definition(_) => panic!("expected Reference, got Definition"), - Group::Reference(ref_) => ref_, - }; - assert_eq!(grp.id.index().unwrap(), want_index); - let got_id = grp.id.to_string(); - let want_id = "group:non-traditional-key".to_owned(); - assert_eq!(got_id, want_id); - let got_doc = grp.documentation(); - let want_doc = ""; - assert_eq!(got_doc, want_doc); - assert_eq!(grp.occurs.min_occurs, 0); - assert!(grp.occurs.max_occurs.is_none()); -} - -#[test] -fn parse_group_reference_max_occurs() { - let xml_str = r#""#; - let doc = exile::parse(xml_str).unwrap(); - let xml = doc.root(); - let want_index: u64 = 3; - let grp = Group::from_xml(&xml, Lineage::Index(want_index), &Xsd::new("xs")).unwrap(); - let grp = match grp { - Group::Definition(_) => panic!("expected Reference, got Definition"), - Group::Reference(ref_) => ref_, - }; - assert_eq!(grp.id.index().unwrap(), want_index); - let got_id = grp.id.to_string(); - let want_id = "group:non-traditional-key".to_owned(); - assert_eq!(got_id, want_id); - let got_doc = grp.documentation(); - let want_doc = ""; - assert_eq!(got_doc, want_doc); - assert_eq!(grp.occurs.min_occurs, 1); - assert_eq!(grp.occurs.max_occurs.unwrap(), 8); -} diff --git a/gen/version-b/src/xsd/id.rs b/gen/version-b/src/xsd/id.rs deleted file mode 100644 index 056bc53e6..000000000 --- a/gen/version-b/src/xsd/id.rs +++ /dev/null @@ -1,271 +0,0 @@ -use crate::error::Result; -use crate::xsd::constants::{ - ANNOTATION, ATTRIBUTE_GROUP, COMPLEX_TYPE, ELEMENT, GROUP, IMPORT, NAME, REF, SIMPLE_TYPE, TYPE, -}; -use std::borrow::Cow; -use std::cmp::Ordering; -use std::collections::hash_map::DefaultHasher; -use std::fmt::{Display, Formatter}; -use std::hash::{Hash, Hasher}; - -#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)] -pub enum Id { - Root(RootNodeId), - Child(ChildNodeId), -} - -impl Id { - pub fn new(type_: RootNodeType, name: String) -> Self { - Id::Root(RootNodeId { - index: None, - type_, - name, - }) - } - - pub fn root_with_index(index: u64, type_: RootNodeType, name: String) -> Self { - Id::Root(RootNodeId { - index: Some(index), - type_, - name, - }) - } - - pub fn child(parent: &Id, type_: S1, name: Option) -> Self - where - S1: AsRef, - S2: AsRef, - { - Id::Child(ChildNodeId { - type_: type_.as_ref().into(), - name: if let Some(s) = name { - Some(s.as_ref().into()) - } else { - None - }, - parent: Box::new(parent.clone()), - }) - } - - pub fn name(&self) -> Cow<'_, str> { - match &self { - Id::Root(r) => r.name(), - Id::Child(c) => c.name(), - } - } - - pub fn parent(&self) -> Option<&Id> { - match self { - Id::Root(_) => None, - Id::Child(ch) => Some(&ch.parent), - } - } - - pub fn index(&self) -> Option { - match self { - Id::Root(r) => r.index, - Id::Child(_) => None, - } - } - - pub fn root_node_type(&self) -> Option { - match self { - Id::Root(r) => Some(r.type_), - Id::Child(_) => None, - } - } - - pub fn display(&self) -> String { - format!("{}", &self) - } - - pub(crate) fn make(lineage: Lineage, node: &exile::Element) -> Result<(Self, Lineage)> { - let attrs = node.attributes.map(); - let name = if let Some(s) = attrs.get("id") { - s.clone() - } else if let Some(s) = attrs.get(NAME) { - s.clone() - } else if let Some(s) = attrs.get(TYPE) { - s.clone() - } else if let Some(s) = attrs.get(REF) { - s.clone() - } else { - let mut hasher = DefaultHasher::new(); - node.hash(&mut hasher); - let result = hasher.finish(); - format!("{}", result) - }; - let type_ = node.name.as_str(); - match lineage { - Lineage::Index(i) => { - let id = Id::Root(RootNodeId { - index: Some(i), - type_: RootNodeType::parse(type_)?, - name: name.into(), - }); - Ok((id.clone(), Lineage::Parent(id.clone()))) - } - Lineage::Parent(p) => { - let id = Id::Child(ChildNodeId { - type_: type_.into(), - name: if name.is_empty() { - None - } else { - Some(name.into()) - }, - parent: Box::new(p), - }); - Ok((id.clone(), Lineage::Parent(id.clone()))) - } - } - } -} - -impl Display for Id { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - match self { - Id::Root(x) => Display::fmt(x, f), - Id::Child(x) => Display::fmt(x, f), - } - } -} - -#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)] -pub enum RootNodeType { - Annotation, - AttributeGroup, - ComplexType, - Element, - Group, - Import, - SimpleType, -} - -impl Display for RootNodeType { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - let s = match self { - RootNodeType::Annotation => ANNOTATION, - RootNodeType::AttributeGroup => ATTRIBUTE_GROUP, - RootNodeType::ComplexType => COMPLEX_TYPE, - RootNodeType::Element => ELEMENT, - RootNodeType::Group => GROUP, - RootNodeType::Import => IMPORT, - RootNodeType::SimpleType => SIMPLE_TYPE, - }; - write!(f, "{}", s) - } -} - -impl RootNodeType { - pub fn parse>(s: S) -> Result { - let et = match s.as_ref() { - ANNOTATION => RootNodeType::Annotation, - ATTRIBUTE_GROUP => RootNodeType::AttributeGroup, - COMPLEX_TYPE => RootNodeType::ComplexType, - ELEMENT => RootNodeType::Element, - GROUP => RootNodeType::Group, - IMPORT => RootNodeType::Import, - SIMPLE_TYPE => RootNodeType::SimpleType, - _ => return raise!("unexpected string '{}'", s.as_ref()), - }; - Ok(et) - } -} - -#[derive(Clone, Debug, Eq)] -pub struct RootNodeId { - index: Option, - type_: RootNodeType, - name: String, -} - -impl RootNodeId { - pub fn index(&self) -> Option { - self.index - } - pub fn name(&self) -> Cow<'_, str> { - Cow::Borrowed(self.name.as_str()) - } - pub fn type_(&self) -> RootNodeType { - self.type_ - } -} - -impl Display for RootNodeId { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "{}:{}", self.type_, self.name.as_str()) - } -} - -impl PartialEq for RootNodeId { - fn eq(&self, other: &Self) -> bool { - self.type_ == other.type_ && self.name == other.name - } -} - -impl Ord for RootNodeId { - fn cmp(&self, other: &Self) -> Ordering { - if let Some(left) = self.index { - if let Some(right) = other.index { - return left.cmp(&right); - } - } - if self.type_ == other.type_ { - self.name.cmp(&other.name) - } else { - self.type_.cmp(&other.type_) - } - } -} - -impl PartialOrd for RootNodeId { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)] -pub struct ChildNodeId { - type_: String, - name: Option, - parent: Box, -} - -impl Display for ChildNodeId { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - Display::fmt(self.parent.as_ref(), f)?; - write!(f, ":{}", self.type_.as_str())?; - if let Some(name) = &self.name { - write!(f, ":{}", name.as_str())?; - } - Ok(()) - } -} - -impl ChildNodeId { - pub fn name(&self) -> Cow<'_, str> { - Cow::Owned(format!("{}", self)) - } -} - -#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)] -pub enum Lineage { - Index(u64), - Parent(Id), -} - -impl Lineage { - pub fn index(&self) -> Option { - match self { - Lineage::Index(i) => Some(*i), - Lineage::Parent(_) => None, - } - } - - pub fn parent(&self) -> Option<&Id> { - match self { - Lineage::Index(_) => None, - Lineage::Parent(id) => Some(id), - } - } -} diff --git a/gen/version-b/src/xsd/import.rs b/gen/version-b/src/xsd/import.rs deleted file mode 100644 index a754665d5..000000000 --- a/gen/version-b/src/xsd/import.rs +++ /dev/null @@ -1,50 +0,0 @@ -use crate::error::Result; - -use crate::xsd::annotation::Annotation; - -use crate::xsd::constants::{ANNOTATION, IMPORT, SCHEMA_LOCATION}; -use crate::xsd::id::{Id, Lineage, RootNodeType}; -use crate::xsd::{namespace_attribute, Xsd}; - -#[derive(Clone, Debug)] -pub struct Import { - pub id: Id, - pub annotation: Option, - pub namespace: String, - pub schema_location: String, -} - -impl Import { - pub fn documentation(&self) -> String { - if let Some(annotation) = &self.annotation { - return annotation.documentation(); - } - return "".to_owned(); - } - - pub fn from_xml(node: &exile::Element, lineage: Lineage, xsd: &Xsd) -> Result { - check!(IMPORT, node, xsd)?; - let (id, lineage) = Id::make(lineage, node)?; - let namespace = namespace_attribute(node)?; - let schema_location = node - .attributes - .map() - .get(SCHEMA_LOCATION) - .ok_or_else(|| make_err!("'{}' attribute not found", SCHEMA_LOCATION))? - .clone(); - let mut annotation = None; - for inner in node.children() { - let t = inner.name.as_str(); - if t == ANNOTATION { - annotation = Some(Annotation::from_xml(inner, lineage.clone(), xsd)?); - break; - } - } - Ok(Import { - id, - annotation, - namespace, - schema_location, - }) - } -} diff --git a/gen/version-b/src/xsd/list.rs b/gen/version-b/src/xsd/list.rs deleted file mode 100644 index a64cf20a1..000000000 --- a/gen/version-b/src/xsd/list.rs +++ /dev/null @@ -1,71 +0,0 @@ -use crate::error::Result; -use crate::xsd::annotation::Annotation; -use crate::xsd::constants::{ANNOTATION, LIST, NAME}; -use crate::xsd::id::{Id, Lineage, RootNodeType}; -use crate::xsd::Xsd; - -#[derive(Clone, Debug)] -pub struct List { - pub id: Id, - pub annotation: Option, - pub item_type: String, -} - -const ITEM_TYPE: &str = "itemType"; - -impl List { - pub fn documentation(&self) -> String { - if let Some(annotation) = &self.annotation { - return annotation.documentation(); - } - return "".to_owned(); - } - - pub fn from_xml(node: &exile::Element, lineage: Lineage, xsd: &Xsd) -> Result { - check!(LIST, node, xsd)?; - let (id, lineage) = Id::make(lineage, node)?; - let item_type = node - .attributes - .map() - .get(ITEM_TYPE) - .ok_or_else(|| make_err!("'{}' attribute not found", ITEM_TYPE))? - .clone(); - let mut annotation = None; - for inner in node.children() { - let t = inner.name.as_str(); - if t == ANNOTATION { - annotation = Some(Annotation::from_xml(inner, lineage.clone(), xsd)?); - break; - } - } - Ok(List { - id, - annotation, - item_type, - }) - } -} - -#[test] -fn parse() { - let parent = crate::xsd::id::Id::new(crate::xsd::id::RootNodeType::Element, "foo".into()); - let lineage = Lineage::Parent(parent); - let xml_str = r#" - - - Hello - - - "#; - let doc = exile::parse(xml_str).unwrap(); - let xml = doc.root(); - let want_id = "element:foo:list:4941444217670409626".to_owned(); - let want_doc = "Hello"; - let list = List::from_xml(&xml, lineage, &Xsd::new("xs")).unwrap(); - let got_doc = list.documentation(); - assert_eq!(got_doc.as_str(), want_doc); - let got_id = format!("{}", list.id); - assert_eq!(got_id, want_id); - let want_item_type = "xs:integer".to_owned(); - assert_eq!(list.item_type, want_item_type); -} diff --git a/gen/version-b/src/xsd/mod.rs b/gen/version-b/src/xsd/mod.rs deleted file mode 100644 index db67004f3..000000000 --- a/gen/version-b/src/xsd/mod.rs +++ /dev/null @@ -1,389 +0,0 @@ -#[macro_use] -// has macros, must go first -mod utils; - -pub mod annotation; -pub mod attribute; -pub mod attribute_group; -pub mod attributes; -pub mod choice; -pub mod common; -pub mod complex_content; -pub mod complex_type; -pub mod constants; -pub mod element; -pub mod extension; -pub mod group; -pub mod id; -pub mod import; -pub mod list; -pub mod primitives; -pub mod restriction; -pub mod sequence; -pub mod simple_content; -pub mod simple_type; -pub mod union; - -use crate::error::Result; -use crate::xsd::annotation::Annotation; -use crate::xsd::attribute_group::AttributeGroup; -use crate::xsd::complex_type::ComplexType; -use crate::xsd::constants::{ - ANNOTATION, ATTRIBUTE_GROUP, BASE, COMPLEX_TYPE, DEFAULT, ELEMENT, FIXED, GROUP, IMPORT, - MAX_OCCURS, MIN_OCCURS, NAME, NAMESPACE, REF, REQUIRED, SIMPLE_TYPE, TYPE, UNBOUNDED, USE, - VALUE, -}; -use crate::xsd::element::Element; -use crate::xsd::group::GroupDefinition; -use crate::xsd::id::{Id, Lineage, RootNodeType}; -use crate::xsd::import::Import; -use crate::xsd::simple_type::SimpleType; -use std::cmp::Ordering; -use std::collections::BTreeMap; -use std::fmt::{Display, Formatter}; -use std::path::Path; - -#[derive(Clone, Debug)] -pub struct Xsd { - entries: Vec, - prefix: String, -} - -impl Default for Xsd { - fn default() -> Self { - Self { - entries: Vec::new(), - prefix: "xs".to_owned(), - } - } -} - -impl Xsd { - pub fn load>(filepath: P) -> Result { - let xml_str = wrap!( - std::fs::read_to_string(filepath.as_ref()), - "unable to load '{}'", - filepath.as_ref().display() - )?; - let doc = exile::parse(&xml_str).unwrap(); - Self::parse(doc.root()) - } - - pub fn parse(root: &exile::Element) -> Result { - if root.name != "schema" { - return raise!("expected the root node to be named 'schema'"); - } - let mut prefix = ""; - for (k, v) in root.attributes.map() { - if v.as_str() == "http://www.w3.org/2001/XMLSchema" { - if k.starts_with("xmlns:") { - let mut split = k.split(':'); - let _ = split.next().ok_or(make_err!("expected to find xmlns:"))?; - let ns: &str = split - .next() - .ok_or(make_err!("expected to find xmlns prefix"))?; - prefix = ns; - break; - } - } - } - if prefix.is_empty() { - return raise!("xmlns prefix is empty"); - } - let mut xsd = Xsd { - entries: Vec::new(), - prefix: prefix.to_owned(), - }; - for (i, entry_node) in root.children().enumerate() { - let entry = Entry::from_xml(entry_node, Lineage::Index(i as u64), &xsd)?; - xsd.add_entry(entry)?; - } - Ok(xsd) - } - - pub fn new>(prefix: S) -> Self { - Self { - entries: Vec::new(), - prefix: prefix.as_ref().into(), - } - } - pub fn prefix(&self) -> &str { - self.prefix.as_str() - } - - pub fn add_entry(&mut self, entry: Entry) -> Result<()> { - // TODO - make an efficient storage - self.entries.push(entry); - Ok(()) - } - - pub fn find(&self, id: &Id) -> Result<&Entry> { - // TODO - make an efficient lookup - for entry in &self.entries { - if entry.id() == id { - return Ok(entry); - } - } - raise!("id '{}' not found", id) - } - - pub fn remove(&mut self, id: &Id) -> Result { - // TODO - efficient removal - let mut pos = None; - for (i, entry) in self.entries.iter().enumerate() { - if entry.id() == id { - pos = Some(i); - break; - } - } - if let Some(i) = pos { - // Note - this can panic, but shouldn't unless a data race occurs. - Ok(self.entries.remove(i)) - } else { - raise!("entry '{}' not found", id) - } - } - - // TODO - this should be an iterator so the underlying data structure can change. - pub fn entries(&self) -> &Vec { - &self.entries - } -} - -impl Display for Xsd { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - for entry in &self.entries { - writeln!(f, "{}", entry.id())?; - } - Ok(()) - } -} - -#[derive(Clone, Debug)] -pub enum Entry { - Annotation(Annotation), - AttributeGroup(AttributeGroup), - ComplexType(ComplexType), - Element(Element), - Group(GroupDefinition), - Import(Import), - SimpleType(SimpleType), -} - -impl Entry { - pub fn from_xml(node: &exile::Element, lineage: Lineage, xsd: &Xsd) -> Result { - let n = node.name.as_str(); - let t = RootNodeType::parse(n)?; - match t { - RootNodeType::Annotation => { - Ok(Entry::Annotation(Annotation::from_xml(node, lineage, xsd)?)) - } - RootNodeType::AttributeGroup => Ok(Entry::AttributeGroup(AttributeGroup::from_xml( - node, lineage, xsd, - )?)), - RootNodeType::ComplexType => Ok(Entry::ComplexType(ComplexType::from_xml( - node, lineage, xsd, - )?)), - RootNodeType::Element => Ok(Entry::Element(Element::from_xml(node, lineage, xsd)?)), - RootNodeType::Group => Ok(Entry::Group(GroupDefinition::from_xml(node, lineage, xsd)?)), - RootNodeType::Import => Ok(Entry::Import(Import::from_xml(node, lineage, xsd)?)), - RootNodeType::SimpleType => { - Ok(Entry::SimpleType(SimpleType::from_xml(node, lineage, xsd)?)) - } - } - } - - pub fn id(&self) -> &Id { - match self { - Entry::Annotation(x) => &x.id, - Entry::AttributeGroup(x) => x.id(), - Entry::ComplexType(x) => &x.id, - Entry::Element(x) => x.id(), - Entry::Group(x) => &x.id, - Entry::Import(x) => &x.id, - Entry::SimpleType(x) => &x.id, - } - } - - pub fn documentation(&self) -> String { - match self { - Entry::Annotation(x) => x.documentation(), - Entry::AttributeGroup(x) => x.documentation(), - Entry::ComplexType(x) => x.documentation(), - Entry::Element(x) => x.documentation(), - Entry::Group(x) => x.documentation(), - Entry::Import(x) => x.documentation(), - Entry::SimpleType(x) => x.documentation(), - } - } -} - -pub(crate) fn get_attribute>( - node: &exile::Element, - attribute_name: S, -) -> Result { - Ok(node - .attributes - .map() - .get(attribute_name.as_ref()) - .ok_or(make_err!( - "'{}' attribute not found in '{}' node", - attribute_name.as_ref(), - node.name.as_str() - ))? - .clone()) -} - -pub(crate) fn name_attribute(node: &exile::Element) -> Result { - get_attribute(node, NAME) -} - -pub(crate) fn namespace_attribute(node: &exile::Element) -> Result { - get_attribute(node, NAMESPACE) -} - -pub(crate) fn value_attribute(node: &exile::Element) -> Result { - get_attribute(node, VALUE) -} - -pub(crate) fn ref_attribute(node: &exile::Element) -> Result { - get_attribute(node, REF) -} - -pub(crate) fn type_attribute(node: &exile::Element) -> Result { - get_attribute(node, TYPE) -} - -pub(crate) fn use_required(node: &exile::Element) -> bool { - match get_attribute(node, USE) { - Ok(val) => val.as_str() == REQUIRED, - Err(_) => false, - } -} - -pub(crate) fn default_attribute(node: &exile::Element) -> Option { - node.attributes.map().get(DEFAULT).cloned() -} - -pub(crate) fn fixed_attribute(node: &exile::Element) -> Option { - node.attributes.map().get(FIXED).cloned() -} - -pub(crate) fn is_ref(node: &exile::Element) -> bool { - node.attributes.map().get(REF).is_some() -} - -pub(crate) fn base_attribute(node: &exile::Element) -> Result { - get_attribute(node, BASE) -} - -#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)] -pub struct Occurs { - pub min_occurs: u64, - - /// None means `unbounded` - pub max_occurs: Option, -} - -impl Default for Occurs { - fn default() -> Self { - Self { - min_occurs: 1, - max_occurs: Some(1), - } - } -} - -impl Occurs { - pub fn from_xml(node: &exile::Element) -> Result { - Ok(Self::from_map(node.attributes.map())?) - } - - pub fn from_map(map: &BTreeMap) -> Result { - let min_occurs: u64 = if let Some(sval) = map.get(MIN_OCCURS) { - wrap!(sval.parse::())? - } else { - 1 - }; - - let max_occurs: Option = if let Some(sval) = map.get(MAX_OCCURS) { - if sval.as_str() == UNBOUNDED { - None - } else { - Some(wrap!(sval.parse::())?) - } - } else { - Some(1) - }; - if let Some(the_max) = max_occurs { - if min_occurs > the_max { - return raise!( - "{} cannot be greater than {}, in this case {} is {} and {} is {}", - MIN_OCCURS, - MAX_OCCURS, - MIN_OCCURS, - min_occurs, - MAX_OCCURS, - the_max - ); - } - } - Ok(Self { - min_occurs, - max_occurs, - }) - } -} - -#[test] -fn parse_occurs() { - let test_cases = vec![ - ( - r#""#, - Occurs { - min_occurs: 1, - max_occurs: Some(1), - }, - ), - ( - r#""#, - Occurs { - min_occurs: 1, - max_occurs: None, - }, - ), - ( - r#""#, - Occurs { - min_occurs: 1, - max_occurs: Some(1), - }, - ), - ( - r#""#, - Occurs { - min_occurs: 2, - max_occurs: Some(3), - }, - ), - ]; - - for (xml, want) in test_cases { - let doc = exile::parse(xml).unwrap(); - let got = Occurs::from_xml(doc.root()).unwrap(); - assert_eq!(got, want) - } -} - -#[test] -fn parse_occurs_err() { - let test_cases = vec![ - r#""#, - r#""#, - ]; - - for xml in test_cases { - let doc = exile::parse(xml).unwrap(); - assert!(Occurs::from_xml(doc.root()).is_err()); - } -} diff --git a/gen/version-b/src/xsd/primitives.rs b/gen/version-b/src/xsd/primitives.rs deleted file mode 100644 index 20da5a056..000000000 --- a/gen/version-b/src/xsd/primitives.rs +++ /dev/null @@ -1,786 +0,0 @@ -use crate::error::{Error, Result}; -use crate::model::builtin::Builtin::Number; -use crate::model::symbol::Symbol; -use crate::xsd::constants::*; -use std::borrow::Cow; -use std::convert::TryFrom; -use std::fmt::{Display, Formatter}; -use std::io::BufRead; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Traits - -pub trait PrefixedParse { - type ParsedThing; - - /// Given a parseable thing, `parseable` return the parsed representation. e.g. - /// `parse_name("something")` might return a `Something` variant. - fn parse>(parseable: S) -> Result; - - /// Given a string `s`, of the format "xs:something", and the expected prefix, e.g. in this case - /// "xs", then parse the string and return the `Something` representation. Returns an error if - /// the string's prefix does not match `prefix`. e.g. `parse("xsd:something", "foo")` returns an - /// error because "xsd" does not equal "foo". - fn parse_prefixed(s: S1, prefix: S2) -> Result - where - S1: AsRef, - S2: AsRef, - { - let (ns, val) = split_raw_str(s.as_ref()); - if ns != prefix.as_ref() { - return raise!( - "wrong namespace prefix. expected '{}', got '{}'", - prefix.as_ref(), - ns - ); - } - Self::parse(val) - } -} - -pub trait PrefixedString: Display { - fn name(&self) -> &str; - - fn as_str(&self, prefix: &str) -> Cow<'_, str> { - let s = self.name(); - if prefix.is_empty() { - Cow::Borrowed(s) - } else { - Cow::Owned(format!("{}:{}", prefix, s)) - } - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// BaseType - -#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] -pub enum BaseType { - // Numerics - Byte, - Decimal, - Int, - Integer, - Long, - NegativeInteger, - NonNegativeInteger, - NonPositiveInteger, - PositiveInteger, - Short, - UnsignedLong, - UnsignedInt, - UnsignedShort, - UnsignedByte, - - // Strings - ID, - IDREF, - Language, - Name, - NmToken, - NormalizedString, - String, - Token, - - // Dates - Date, - DateTime, - Duration, - GDay, - GMonth, - GMonthDay, - GYear, - GYearMonth, - Time, - - // Custom - Custom(String), -} - -impl PrefixedParse for BaseType { - type ParsedThing = BaseType; - - fn parse>(parseable: S) -> Result { - let s = parseable.as_ref(); - match s { - BYTE => Ok(BaseType::Byte), - DECIMAL => Ok(BaseType::Decimal), - INT => Ok(BaseType::Int), - INTEGER => Ok(BaseType::Integer), - LONG => Ok(BaseType::Long), - NEGATIVE_INTEGER => Ok(BaseType::NegativeInteger), - NON_NEGATIVE_INTEGER => Ok(BaseType::NonNegativeInteger), - NON_POSITIVE_INTEGER => Ok(BaseType::NonPositiveInteger), - POSITIVE_INTEGER => Ok(BaseType::PositiveInteger), - SHORT => Ok(BaseType::Short), - UNSIGNED_LONG => Ok(BaseType::UnsignedLong), - UNSIGNED_INT => Ok(BaseType::UnsignedInt), - UNSIGNED_SHORT => Ok(BaseType::UnsignedShort), - UNSIGNED_BYTE => Ok(BaseType::UnsignedByte), - // - ID => Ok(BaseType::ID), - IDREF => Ok(BaseType::IDREF), - LANGUAGE => Ok(BaseType::Language), - NAME => Ok(BaseType::Name), - NMTOKEN => Ok(BaseType::NmToken), - NORMALIZED_STRING => Ok(BaseType::NormalizedString), - STRING => Ok(BaseType::String), - TOKEN => Ok(BaseType::Token), - // - DATE => Ok(BaseType::Date), - DATETIME => Ok(BaseType::DateTime), - DURATION => Ok(BaseType::Duration), - G_DAY => Ok(BaseType::GDay), - G_MONTH => Ok(BaseType::GMonth), - G_MONTH_DAY => Ok(BaseType::GMonthDay), - G_YEAR => Ok(BaseType::GYear), - G_YEAR_MONTH => Ok(BaseType::GYearMonth), - TIME => Ok(BaseType::Time), - // - custom => Ok(BaseType::Custom(custom.into())), - } - } - - fn parse_prefixed(s: S1, prefix: S2) -> Result - where - S1: AsRef, - S2: AsRef, - { - let prefix = prefix.as_ref(); - let s = s.as_ref(); - let (ns, val) = split_raw_str(s); - if ns != prefix { - return Ok(BaseType::Custom(s.into())); - } - Ok(match Self::parse(val)? { - BaseType::Custom(_) => BaseType::Custom(s.into()), - anything_else => anything_else, - }) - } -} - -impl PrefixedString for BaseType { - fn name(&self) -> &str { - match self { - // Numerics - BaseType::Byte => BYTE, - BaseType::Decimal => DECIMAL, - BaseType::Int => INT, - BaseType::Integer => INTEGER, - BaseType::Long => LONG, - BaseType::NegativeInteger => NEGATIVE_INTEGER, - BaseType::NonNegativeInteger => NON_NEGATIVE_INTEGER, - BaseType::NonPositiveInteger => NON_POSITIVE_INTEGER, - BaseType::PositiveInteger => POSITIVE_INTEGER, - BaseType::Short => SHORT, - BaseType::UnsignedLong => UNSIGNED_LONG, - BaseType::UnsignedInt => UNSIGNED_INT, - BaseType::UnsignedShort => UNSIGNED_SHORT, - BaseType::UnsignedByte => UNSIGNED_BYTE, - // Strings - BaseType::ID => ID, - BaseType::IDREF => IDREF, - BaseType::Language => LANGUAGE, - BaseType::Name => NAME, - BaseType::NmToken => NMTOKEN, - BaseType::NormalizedString => NORMALIZED_STRING, - BaseType::String => STRING, - BaseType::Token => TOKEN, - // Dates - BaseType::Date => DATE, - BaseType::DateTime => DATETIME, - BaseType::Duration => DURATION, - BaseType::GDay => G_DAY, - BaseType::GMonth => G_MONTH, - BaseType::GMonthDay => G_MONTH_DAY, - BaseType::GYear => G_YEAR, - BaseType::GYearMonth => G_YEAR_MONTH, - BaseType::Time => TIME, - // Custom - BaseType::Custom(o) => o.as_str(), - } - } -} - -impl Display for BaseType { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.name()) - } -} - -impl BaseType { - pub fn primitive(&self) -> Primitive { - match self { - // Numerics - BaseType::Byte => Primitive::Numeric, - BaseType::Decimal => Primitive::Numeric, - BaseType::Int => Primitive::Numeric, - BaseType::Integer => Primitive::Numeric, - BaseType::Long => Primitive::Numeric, - BaseType::NegativeInteger => Primitive::Numeric, - BaseType::NonNegativeInteger => Primitive::Numeric, - BaseType::NonPositiveInteger => Primitive::Numeric, - BaseType::PositiveInteger => Primitive::Numeric, - BaseType::Short => Primitive::Numeric, - BaseType::UnsignedLong => Primitive::Numeric, - BaseType::UnsignedInt => Primitive::Numeric, - BaseType::UnsignedShort => Primitive::Numeric, - BaseType::UnsignedByte => Primitive::Numeric, - // Strings - BaseType::ID => Primitive::Character, - BaseType::IDREF => Primitive::Character, - BaseType::Language => Primitive::Character, - BaseType::Name => Primitive::Character, - BaseType::NmToken => Primitive::Character, - BaseType::NormalizedString => Primitive::Character, - BaseType::String => Primitive::Character, - BaseType::Token => Primitive::Character, - // Dates - BaseType::Date => Primitive::DateType, - BaseType::DateTime => Primitive::DateType, - BaseType::Duration => Primitive::DateType, - BaseType::GDay => Primitive::DateType, - BaseType::GMonth => Primitive::DateType, - BaseType::GMonthDay => Primitive::DateType, - BaseType::GYear => Primitive::DateType, - BaseType::GYearMonth => Primitive::DateType, - BaseType::Time => Primitive::DateType, - // Custom - BaseType::Custom(o) => Primitive::None, - } - } - - pub fn is_numeric(&self) -> bool { - self.primitive() == Primitive::Numeric - } - - pub fn is_character(&self) -> bool { - self.primitive() == Primitive::Character - } - - pub fn is_datetype(&self) -> bool { - self.primitive() == Primitive::DateType - } - - pub fn is_custom(&self) -> bool { - self.primitive() == Primitive::None - } - - pub fn as_numeric(&self) -> Option { - match self { - BaseType::Byte => Some(Numeric::Byte), - BaseType::Decimal => Some(Numeric::Decimal), - BaseType::Int => Some(Numeric::Int), - BaseType::Integer => Some(Numeric::Integer), - BaseType::Long => Some(Numeric::Long), - BaseType::NegativeInteger => Some(Numeric::NegativeInteger), - BaseType::NonNegativeInteger => Some(Numeric::NonNegativeInteger), - BaseType::NonPositiveInteger => Some(Numeric::NonPositiveInteger), - BaseType::PositiveInteger => Some(Numeric::PositiveInteger), - BaseType::Short => Some(Numeric::Short), - BaseType::UnsignedLong => Some(Numeric::UnsignedLong), - BaseType::UnsignedInt => Some(Numeric::UnsignedInt), - BaseType::UnsignedShort => Some(Numeric::UnsignedShort), - BaseType::UnsignedByte => Some(Numeric::UnsignedByte), - _ => None, - } - } - - pub fn as_character(&self) -> Option { - match self { - BaseType::ID => Some(Character::ID), - BaseType::IDREF => Some(Character::IDREF), - BaseType::Language => Some(Character::Language), - BaseType::Name => Some(Character::Name), - BaseType::NmToken => Some(Character::NmToken), - BaseType::NormalizedString => Some(Character::NormalizedString), - BaseType::String => Some(Character::String), - BaseType::Token => Some(Character::Token), - _ => None, - } - } - - pub fn as_datetime(&self) -> Option { - match self { - BaseType::Date => Some(DateTime::Date), - BaseType::DateTime => Some(DateTime::DateTime), - BaseType::Duration => Some(DateTime::Duration), - BaseType::GDay => Some(DateTime::GDay), - BaseType::GMonth => Some(DateTime::GMonth), - BaseType::GMonthDay => Some(DateTime::GMonthDay), - BaseType::GYear => Some(DateTime::GYear), - BaseType::GYearMonth => Some(DateTime::GYearMonth), - BaseType::Time => Some(DateTime::Time), - _ => None, - } - } - - pub fn to_symbol(&self) -> Symbol { - Symbol::new(format!("{}", self)) - } - - // pub fn parse_prefixed_or_custom(s: S1, prefix: S2) -> Self - // where - // S1: AsRef, - // S2: AsRef, - // { - // match Self::parse_prefixed(&s, &prefix) { - // Ok(ok) => ok, - // Err(_) => { - // if prefix.as_ref().is_empty() { - // - // } else { - // BaseType::Custom(format!("{}:{}", prefix.as_ref(), s.as_ref())) - // } - // } - // } - // } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Primitive - -#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] -pub enum Primitive { - None, - Numeric, - Character, - DateType, -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Numeric Types - -#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] -pub enum Numeric { - Byte, - Decimal, - Int, - Integer, - Long, - NegativeInteger, - NonNegativeInteger, - NonPositiveInteger, - PositiveInteger, - Short, - UnsignedLong, - UnsignedInt, - UnsignedShort, - UnsignedByte, -} - -impl Default for Numeric { - fn default() -> Self { - Numeric::Int - } -} - -impl PrefixedParse for Numeric { - type ParsedThing = Numeric; - - fn parse>(parseable: S) -> Result { - match parseable.as_ref() { - BYTE => Ok(Numeric::Byte), - DECIMAL => Ok(Numeric::Decimal), - INT => Ok(Numeric::Int), - INTEGER => Ok(Numeric::Integer), - LONG => Ok(Numeric::Long), - NEGATIVE_INTEGER => Ok(Numeric::NegativeInteger), - NON_NEGATIVE_INTEGER => Ok(Numeric::NonNegativeInteger), - NON_POSITIVE_INTEGER => Ok(Numeric::NonPositiveInteger), - POSITIVE_INTEGER => Ok(Numeric::PositiveInteger), - SHORT => Ok(Numeric::Short), - UNSIGNED_LONG => Ok(Numeric::UnsignedLong), - UNSIGNED_INT => Ok(Numeric::UnsignedInt), - UNSIGNED_SHORT => Ok(Numeric::UnsignedShort), - UNSIGNED_BYTE => Ok(Numeric::UnsignedByte), - _ => raise!("unknown numeric type: '{}'", parseable.as_ref()), - } - } -} - -impl PrefixedString for Numeric { - fn name(&self) -> &str { - let s = match self { - Numeric::Byte => BYTE, - Numeric::Decimal => DECIMAL, - Numeric::Int => INT, - Numeric::Integer => INTEGER, - Numeric::Long => LONG, - Numeric::NegativeInteger => NEGATIVE_INTEGER, - Numeric::NonNegativeInteger => NON_NEGATIVE_INTEGER, - Numeric::NonPositiveInteger => NON_POSITIVE_INTEGER, - Numeric::PositiveInteger => POSITIVE_INTEGER, - Numeric::Short => SHORT, - Numeric::UnsignedLong => UNSIGNED_LONG, - Numeric::UnsignedInt => UNSIGNED_INT, - Numeric::UnsignedShort => UNSIGNED_SHORT, - Numeric::UnsignedByte => UNSIGNED_BYTE, - }; - s - } -} - -impl Display for Numeric { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.name()) - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// String Types - named Character for disambiguation - -#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] -pub enum Character { - ID, - IDREF, - Language, - Name, - NmToken, - NormalizedString, - String, - Token, -} - -impl Default for Character { - fn default() -> Self { - Character::String - } -} - -impl PrefixedParse for Character { - type ParsedThing = Character; - - fn parse>(parseable: S) -> Result { - match parseable.as_ref() { - ID => Ok(Character::ID), - IDREF => Ok(Character::IDREF), - LANGUAGE => Ok(Character::Language), - NAME => Ok(Character::Name), - NMTOKEN => Ok(Character::NmToken), - NORMALIZED_STRING => Ok(Character::NormalizedString), - STRING => Ok(Character::String), - TOKEN => Ok(Character::Token), - _ => raise!("unknown string type: '{}'", parseable.as_ref()), - } - } -} - -impl PrefixedString for Character { - fn name(&self) -> &str { - let s = match self { - Character::ID => ID, - Character::IDREF => IDREF, - Character::Language => LANGUAGE, - Character::Name => NAME, - Character::NmToken => NMTOKEN, - Character::NormalizedString => NORMALIZED_STRING, - Character::String => STRING, - Character::Token => TOKEN, - }; - s - } -} - -impl Display for Character { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.name()) - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// DateTime Types - -#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] -pub enum DateTime { - Date, - DateTime, - Duration, - GDay, - GMonth, - GMonthDay, - GYear, - GYearMonth, - Time, -} - -impl PrefixedParse for DateTime { - type ParsedThing = DateTime; - - fn parse>(parseable: S) -> Result { - match parseable.as_ref() { - DATE => Ok(DateTime::Date), - DATETIME => Ok(DateTime::DateTime), - DURATION => Ok(DateTime::Duration), - G_DAY => Ok(DateTime::GDay), - G_MONTH => Ok(DateTime::GMonth), - G_MONTH_DAY => Ok(DateTime::GMonthDay), - G_YEAR => Ok(DateTime::GYear), - G_YEAR_MONTH => Ok(DateTime::GYearMonth), - TIME => Ok(DateTime::Time), - _ => raise!("unknown datetime type: '{}'", parseable.as_ref()), - } - } -} - -impl PrefixedString for DateTime { - fn name(&self) -> &str { - let s = match self { - DateTime::Date => DATE, - DateTime::DateTime => DATETIME, - DateTime::Duration => DURATION, - DateTime::GDay => G_DAY, - DateTime::GMonth => G_MONTH, - DateTime::GMonthDay => G_MONTH_DAY, - DateTime::GYear => G_YEAR, - DateTime::GYearMonth => G_YEAR_MONTH, - DateTime::Time => TIME, - }; - s - } -} - -impl Display for DateTime { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.name()) - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Conveniences - -impl BaseType { - pub fn is_id(&self) -> bool { - *self == BaseType::ID - } - pub fn is_idref(&self) -> bool { - *self == BaseType::IDREF - } - pub fn is_language(&self) -> bool { - *self == BaseType::Language - } - pub fn is_name(&self) -> bool { - *self == BaseType::Name - } - pub fn is_nmtoken(&self) -> bool { - *self == BaseType::NmToken - } - pub fn is_normalized_string(&self) -> bool { - *self == BaseType::NormalizedString - } - pub fn is_string(&self) -> bool { - *self == BaseType::String - } - pub fn is_token(&self) -> bool { - *self == BaseType::Token - } - pub fn is_byte(&self) -> bool { - *self == BaseType::Byte - } - pub fn is_decimal(&self) -> bool { - *self == BaseType::Decimal - } - pub fn is_int(&self) -> bool { - *self == BaseType::Int - } - pub fn is_integer(&self) -> bool { - *self == BaseType::Integer - } - pub fn is_long(&self) -> bool { - *self == BaseType::Long - } - pub fn is_negative_integer(&self) -> bool { - *self == BaseType::NegativeInteger - } - pub fn is_non_negative_integer(&self) -> bool { - *self == BaseType::NonNegativeInteger - } - pub fn is_non_positive_integer(&self) -> bool { - *self == BaseType::PositiveInteger - } - pub fn is_positive_integer(&self) -> bool { - *self == BaseType::NonPositiveInteger - } - pub fn is_short(&self) -> bool { - *self == BaseType::Short - } - pub fn is_unsigned_long(&self) -> bool { - *self == BaseType::UnsignedLong - } - pub fn is_unsigned_int(&self) -> bool { - *self == BaseType::UnsignedInt - } - pub fn is_unsigned_short(&self) -> bool { - *self == BaseType::UnsignedShort - } - pub fn is_unsigned_byte(&self) -> bool { - *self == BaseType::UnsignedByte - } - pub fn is_date(&self) -> bool { - *self == BaseType::Date - } - pub fn is_datetime(&self) -> bool { - *self == BaseType::DateTime - } - pub fn is_duration(&self) -> bool { - *self == BaseType::Duration - } - pub fn is_gday(&self) -> bool { - *self == BaseType::GDay - } - pub fn is_gmonth(&self) -> bool { - *self == BaseType::GMonth - } - pub fn is_gmonthday(&self) -> bool { - *self == BaseType::GMonthDay - } - pub fn is_gyear(&self) -> bool { - *self == BaseType::GYear - } - pub fn is_gyearmonth(&self) -> bool { - *self == BaseType::GYearMonth - } - pub fn is_time(&self) -> bool { - *self == BaseType::Time - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Helpers - -fn split_raw_str(raw_str: &str) -> (&str, &str) { - let mut split = raw_str.split(":"); - let mut ns: &str = split.next().unwrap_or(""); - let mut val: &str = split.next().unwrap_or(""); - if val.is_empty() && !ns.is_empty() { - // if there no val but there is an ns, then it means that ns was actually the val. - // e.g. "blah" -> ns="blah" val="", so we swap to ns="" val="blah" - val = ns; - ns = ""; - } - (ns, val) -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Tests - -#[test] -fn split_no_ns() { - let input = "bloop"; - let got = split_raw_str(input); - let want = ("", "bloop"); - assert_eq!(got, want); -} - -#[test] -fn split_with_ns() { - let input = "x:bloop"; - let got = split_raw_str(input); - let want = ("x", "bloop"); - assert_eq!(got, want); -} - -#[test] -fn numeric_parse_prefixed() { - let input = "xs:decimal"; - let got = Numeric::parse_prefixed(input, "xs").unwrap(); - let want = Numeric::Decimal; - assert_eq!(got, want); -} - -#[test] -fn numeric_parse_bad_prefix() { - let input = "foo:decimal"; - let result = Numeric::parse_prefixed(input, "bar"); - assert!(result.is_err()); -} - -#[test] -fn numeric_parse_bad_value() { - let input = "xs:decimate"; - let result = Numeric::parse_prefixed(input, "xs"); - assert!(result.is_err()); -} - -#[test] -fn parse_primitive_xs_datetime() { - let input = "xs:dateTime"; - let got = BaseType::parse_prefixed(input, "xs").unwrap(); - let want = BaseType::DateTime; - assert_eq!(got, want); -} - -#[test] -fn parse_primitive_xs_string() { - let input = "xs:string"; - let got = BaseType::parse_prefixed(input, "xs").unwrap(); - let want = BaseType::String; - assert_eq!(got, want); -} - -#[test] -fn parse_primitive_xs_byte() { - let input = "floop:byte"; - let got = BaseType::parse_prefixed(input, "floop").unwrap(); - let want = BaseType::Byte; - assert_eq!(got, want); -} - -#[test] -fn parse_base_type() { - struct TestCase { - prefix: &'static str, - input: &'static str, - want: BaseType, - } - let test_cases = vec![TestCase { - prefix: "xs", - input: "xs:string", - want: BaseType::String, - }]; - for test_case in &test_cases { - let got = BaseType::parse_prefixed(test_case.input, test_case.prefix).unwrap(); - assert_eq!(&got, &test_case.want); - } -} - -#[test] -fn parse_base_type_custom() { - struct TestCase { - prefix: &'static str, - input: &'static str, - want: BaseType, - } - let test_cases = vec![ - TestCase { - prefix: "foo", - input: "foo:bar", - want: BaseType::Custom("foo:bar".to_owned()), - }, - TestCase { - prefix: "xs", - input: "bloop:blerp", - want: BaseType::Custom("bloop:blerp".to_owned()), - }, - ]; - for test_case in &test_cases { - let got = BaseType::parse_prefixed(test_case.input, test_case.prefix).unwrap(); - assert_eq!(&got, &test_case.want); - } -} - -#[test] -fn display_numeric() { - let numeric = Numeric::Byte; - let got = format!("{}", numeric); - let want = "byte"; - assert_eq!(got.as_str(), want); -} - -#[test] -fn display_base_type() { - let base_type = BaseType::Byte; - let got = format!("{}", base_type); - let want = "byte"; - assert_eq!(got.as_str(), want); -} diff --git a/gen/version-b/src/xsd/restriction.rs b/gen/version-b/src/xsd/restriction.rs deleted file mode 100644 index ba14c4127..000000000 --- a/gen/version-b/src/xsd/restriction.rs +++ /dev/null @@ -1,259 +0,0 @@ -use crate::error::Result; -use crate::xsd::annotation::Annotation; -use crate::xsd::constants::{ - ANNOTATION, ENUMERATION, LENGTH, MAX_EXCLUSIVE, MAX_INCLUSIVE, MAX_LENGTH, MIN_EXCLUSIVE, - MIN_INCLUSIVE, MIN_LENGTH, NAME, PATTERN, RESTRICTION, -}; -use crate::xsd::restriction::FacetType::Pattern; -use crate::xsd::{base_attribute, value_attribute, Xsd}; -use exile::Element; - -use crate::xsd::id::{Id, Lineage, RootNodeType}; -use crate::xsd::primitives::{BaseType, Numeric, PrefixedParse, Primitive}; -use std::fmt::{Display, Formatter}; - -/* -enumeration Defines a list of acceptable values -fractionDigits Specifies the maximum number of decimal places allowed. Must be equal to or greater than zero -length Specifies the exact number of characters or list items allowed. Must be equal to or greater than zero -maxExclusive Specifies the upper bounds for numeric values (the value must be less than this value) -maxInclusive Specifies the upper bounds for numeric values (the value must be less than or equal to this value) -maxLength Specifies the maximum number of characters or list items allowed. Must be equal to or greater than zero -minExclusive Specifies the lower bounds for numeric values (the value must be greater than this value) -minInclusive Specifies the lower bounds for numeric values (the value must be greater than or equal to this value) -minLength Specifies the minimum number of characters or list items allowed. Must be equal to or greater than zero -pattern Defines the exact sequence of characters that are acceptable -totalDigits Specifies the exact number of digits allowed. Must be greater than zero -whiteSpace Specifies how white space (line feeds, tabs, spaces, and carriage returns) is handled - */ - -/* - - -Content for simpleType: -(annotation?,(simpleType?,(minExclusive|minInclusive| -maxExclusive|maxInclusive|totalDigits|fractionDigits| -length|minLength|maxLength|enumeration|whiteSpace|pattern)*)) - */ - -/* - - Content: (annotation?, (simpleType?, (minExclusive | minInclusive | maxExclusive | maxInclusive | - totalDigits | fractionDigits | length | minLength | maxLength | enumeration | whiteSpace | - pattern | assertion | explicitTimezone | {any with namespace: ##other})*)) - - */ - -/// Restriction facets. Note, not all are supported. -#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd)] -pub enum FacetType { - Enumeration, - Length, - MaxExclusive, - MaxInclusive, - MaxLength, - MinExclusive, - MinInclusive, - MinLength, - Pattern, -} - -impl Display for FacetType { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - let s = match self { - FacetType::Enumeration => ENUMERATION, - FacetType::Length => LENGTH, - FacetType::MaxExclusive => MAX_EXCLUSIVE, - FacetType::MaxInclusive => MAX_INCLUSIVE, - FacetType::MaxLength => MAX_LENGTH, - FacetType::MinExclusive => MIN_EXCLUSIVE, - FacetType::MinInclusive => MIN_INCLUSIVE, - FacetType::MinLength => MIN_LENGTH, - FacetType::Pattern => PATTERN, - }; - write!(f, "{}", s) - } -} - -impl FacetType { - fn parse>(s: S) -> Result { - let s = s.as_ref(); - match s { - ENUMERATION => Ok(FacetType::Enumeration), - LENGTH => Ok(FacetType::Length), - MAX_EXCLUSIVE => Ok(FacetType::MaxExclusive), - MAX_INCLUSIVE => Ok(FacetType::MaxInclusive), - MAX_LENGTH => Ok(FacetType::MaxLength), - MIN_EXCLUSIVE => Ok(FacetType::MinExclusive), - MIN_INCLUSIVE => Ok(FacetType::MinInclusive), - MIN_LENGTH => Ok(FacetType::MinLength), - PATTERN => Ok(FacetType::Pattern), - _ => raise!("unsupported or invalid facet type {}", s), - } - } -} - -#[derive(Debug, Clone, Copy, PartialEq)] -pub enum Number { - Integer(i64), - Decimal(f64), -} - -impl Number { - fn parse>(s: S) -> Result { - if let Ok(i) = s.as_ref().parse::() { - return Ok(Number::Integer(i)); - } - Ok(Number::Decimal(wrap!(s.as_ref().parse::())?)) - } -} - -#[derive(Debug, Clone, PartialEq)] -pub enum Facet { - Enumeration(String), - Length(u64), - MaxExclusive(Number), - MaxInclusive(Number), - MaxLength(u64), - MinExclusive(Number), - MinInclusive(Number), - MinLength(u64), - Pattern(String), -} - -impl Facet { - fn from_xml(node: &Element, xsd: &Xsd) -> Result { - check!(FACET, node, xsd)?; - let t = FacetType::parse(&node.name)?; - let v = value_attribute(node)?; - let result = match t { - FacetType::Enumeration => Facet::Enumeration(v.clone()), - FacetType::Length => { - let x = wrap!(v.parse::())?; - Facet::Length(x) - } - FacetType::MaxExclusive => { - let n = Number::parse(v)?; - Facet::MaxExclusive(n) - } - FacetType::MaxInclusive => { - let n = Number::parse(v)?; - Facet::MaxInclusive(n) - } - FacetType::MaxLength => { - let x = wrap!(v.parse::())?; - Facet::MaxLength(x) - } - FacetType::MinExclusive => { - let n = Number::parse(v)?; - Facet::MinExclusive(n) - } - FacetType::MinInclusive => { - let n = Number::parse(v)?; - Facet::MinInclusive(n) - } - FacetType::MinLength => { - let x = wrap!(v.parse::())?; - Facet::MinLength(x) - } - Pattern => Facet::Pattern(v.clone()), - }; - Ok(result) - } -} - -#[derive(Clone, Debug)] -pub struct Restriction { - pub id: Id, - pub annotation: Option, - pub base: BaseType, - pub facets: Vec, -} - -impl Restriction { - pub fn documentation(&self) -> String { - if let Some(annotation) = &self.annotation { - return annotation.documentation(); - } - return "".to_owned(); - } - - pub fn from_xml(node: &exile::Element, lineage: Lineage, xsd: &Xsd) -> Result { - check!(RESTRICTION, node, xsd)?; - let (id, lineage) = Id::make(lineage, node)?; - let base = base_attribute(node)?; - let base = BaseType::parse_prefixed(base.as_str(), xsd.prefix.as_str())?; - let mut annotation = None; - let mut facets = Vec::new(); - for inner in node.children() { - let t = inner.name.as_str(); - if t == ANNOTATION { - annotation = Some(Annotation::from_xml(inner, lineage.clone(), xsd)?); - } else { - let facet = Facet::from_xml(inner, xsd)?; - facets.push(facet); - } - } - - Ok(Restriction { - id, - annotation, - base, - facets, - }) - } -} - -#[test] -fn parse() { - let parent = crate::xsd::id::Id::new(crate::xsd::id::RootNodeType::Element, "foo".into()); - let lineage = Lineage::Parent(parent); - let xml_str = r#" - - - - - "#; - let doc = exile::parse(xml_str).unwrap(); - let xml = doc.root(); - let want_id = "element:foo:restriction:18375205485067440936".to_owned(); - let want_doc = ""; - let r = Restriction::from_xml(&xml, lineage, &Xsd::new("xs")).unwrap(); - let got_doc = r.documentation(); - assert_eq!(got_doc.as_str(), want_doc); - let got_id = format!("{}", r.id); - assert_eq!(got_id, want_id); - // let got_type = r.id.entry_type; - // assert_eq!(got_type, RootNodeType::Other(RESTRICTION.to_owned())); - let got_base = r.base; - let want_base = BaseType::PositiveInteger; - assert_eq!(got_base, want_base); - assert_eq!(r.facets.len(), 2); - let min = r.facets.get(0).unwrap(); - if let Facet::MinInclusive(n) = min { - if let Number::Integer(i) = n { - assert_eq!(*i, 1); - } else { - panic!("wrong number type"); - } - } else { - panic!("wrong facet type"); - } - let max = r.facets.get(1).unwrap(); - if let Facet::MaxInclusive(n) = max { - if let Number::Integer(i) = n { - assert_eq!(*i, 8); - } else { - panic!("wrong number type"); - } - } else { - panic!("wrong facet type"); - } -} diff --git a/gen/version-b/src/xsd/sequence.rs b/gen/version-b/src/xsd/sequence.rs deleted file mode 100644 index 536e4fefc..000000000 --- a/gen/version-b/src/xsd/sequence.rs +++ /dev/null @@ -1,123 +0,0 @@ -use crate::error::Result; -use crate::xsd::annotation::Annotation; -use crate::xsd::choice::Choice; -use crate::xsd::constants::{ANNOTATION, CHOICE, ELEMENT, GROUP, NAME, SEQUENCE}; -use crate::xsd::element::Element; -use crate::xsd::group::Group; -use crate::xsd::id::{Id, Lineage, RootNodeType}; -use crate::xsd::{Occurs, Xsd}; - -#[derive(Clone, Debug)] -pub struct Sequence { - pub id: Id, - pub annotation: Option, - pub occurs: Occurs, - pub members: Vec, -} - -#[derive(Clone, Debug)] -pub enum Member { - Choice(Choice), - Element(Element), - Group(Group), - Sequence(Sequence), -} - -impl Sequence { - pub fn documentation(&self) -> String { - if let Some(annotation) = &self.annotation { - return annotation.documentation(); - } - return "".to_owned(); - } - - pub fn from_xml(node: &exile::Element, lineage: Lineage, xsd: &Xsd) -> Result { - check!(SEQUENCE, node, xsd)?; - let (id, lineage) = Id::make(lineage, node)?; - let mut annotation = None; - let mut members = Vec::new(); - for inner in node.children() { - let t = inner.name.as_str(); - match t { - ANNOTATION => annotation = Some(Annotation::from_xml(inner, lineage.clone(), xsd)?), - CHOICE => members.push(Member::Choice(Choice::from_xml( - inner, - lineage.clone(), - xsd, - )?)), - ELEMENT => members.push(Member::Element(Element::from_xml( - inner, - lineage.clone(), - xsd, - )?)), - GROUP => members.push(Member::Group(Group::from_xml(inner, lineage.clone(), xsd)?)), - SEQUENCE => members.push(Member::Sequence(Sequence::from_xml( - inner, - lineage.clone(), - xsd, - )?)), - _ => return raise!("unknown {} member: '{}'", SEQUENCE, t), - } - } - Ok(Sequence { - id, - annotation, - occurs: Occurs::from_xml(node)?, - members, - }) - } -} - -#[test] -fn parse() { - let parent = crate::xsd::id::Id::new(crate::xsd::id::RootNodeType::Element, "foo".into()); - let lineage = Lineage::Parent(parent); - let xml_str = r#" - - - - - - - - - flerp floop fleep flop - - - - - - - - "#; - let doc = exile::parse(xml_str).unwrap(); - let xml = doc.root(); - let want_index: u64 = 3; - let seq = Sequence::from_xml(&xml, lineage, &Xsd::new("xs")).unwrap(); - let got_id = format!("{}", seq.id); - let want_id = "element:foo:sequence:12280079412076832312"; - assert_eq!(got_id.as_str(), want_id); - let got_doc = seq.documentation(); - let want_doc = ""; - assert_eq!(got_doc, want_doc); - assert_eq!( - seq.occurs, - Occurs { - min_occurs: 1, - max_occurs: Some(1), - } - ); - assert_eq!(seq.members.len(), 8); - match seq.members.get(5).unwrap() { - Member::Choice(_) => panic!("expecting '{}', got '{}'", "Element", "Choice"), - Member::Element(_) => {} - Member::Group(_) => panic!("expecting '{}', got '{}'", "Element", "Group"), - Member::Sequence(_) => panic!("expecting '{}', got '{}'", "Element", "Sequence"), - }; - match seq.members.get(7).unwrap() { - Member::Choice(_) => panic!("expecting '{}', got '{}'", "Sequence", "Choice"), - Member::Element(_e) => panic!("expecting '{}', got '{}'", "Sequence", "Element"), - Member::Group(_) => panic!("expecting '{}', got '{}'", "Sequence", "Group"), - Member::Sequence(_) => {} - }; -} diff --git a/gen/version-b/src/xsd/simple_content.rs b/gen/version-b/src/xsd/simple_content.rs deleted file mode 100644 index ccad13824..000000000 --- a/gen/version-b/src/xsd/simple_content.rs +++ /dev/null @@ -1,98 +0,0 @@ -use crate::error::Result; -use crate::xsd::annotation::Annotation; -use crate::xsd::constants::{ANNOTATION, EXTENSION, NAME, SIMPLE_CONTENT}; -use crate::xsd::extension::Extension; -use crate::xsd::id::{Id, Lineage, RootNodeType}; -use crate::xsd::Xsd; - -#[derive(Clone, Debug)] -pub struct SimpleContent { - pub id: Id, - pub annotation: Option, - pub payload: Payload, -} - -#[derive(Clone, Debug)] -pub enum Payload { - Extension(Extension), -} - -impl SimpleContent { - pub fn documentation(&self) -> String { - if let Some(annotation) = &self.annotation { - return annotation.documentation(); - } - return "".to_owned(); - } - - pub fn from_xml(node: &exile::Element, lineage: Lineage, xsd: &Xsd) -> Result { - check!(SIMPLE_CONTENT, node, xsd)?; - let (id, lineage) = Id::make(lineage, node)?; - let mut annotation = None; - let mut payload = None; - for inner in node.children() { - let t = inner.name.as_str(); - match t { - ANNOTATION => annotation = Some(Annotation::from_xml(inner, lineage.clone(), xsd)?), - EXTENSION => { - payload = Some(Payload::Extension(Extension::from_xml( - inner, - lineage.clone(), - xsd, - )?)); - } - _ => return raise!("unsupported simpleContent node '{}'", t), - } - } - let payload = if let Some(p) = payload { - p - } else { - return raise!("{} payload was not found", SIMPLE_CONTENT); - }; - Ok(SimpleContent { - id, - annotation, - payload, - }) - } -} - -#[test] -fn parse() { - use super::attribute_group::AttributeGroup; - use super::attributes::AttributeItem; - let parent = crate::xsd::id::Id::new(crate::xsd::id::RootNodeType::Element, "foo".into()); - let lineage = Lineage::Parent(parent); - let xml_str = r#" - - - - - "#; - let doc = exile::parse(xml_str).unwrap(); - let xml = doc.root(); - let want_id = "element:foo:simpleContent:17852308769138094955".to_owned(); - let want_doc = ""; - let sc = SimpleContent::from_xml(&xml, lineage, &Xsd::new("xs")).unwrap(); - let got_doc = sc.documentation(); - assert_eq!(got_doc.as_str(), want_doc); - let got_id = format!("{}", sc.id); - assert_eq!(got_id, want_id); - // let got_type = sc.id.entry_type; - // assert_eq!(got_type, RootNodeType::Other(SIMPLE_CONTENT.to_owned())); - match sc.payload { - Payload::Extension(ext) => { - assert_eq!(ext.attributes.len(), 1); - let a = ext.attributes.get(0).unwrap(); - match a { - AttributeItem::Attribute(_) => { - panic!("expected 'AttributeGroup' but got 'Attribute'") - } - AttributeItem::AttributeGroup(x) => match x { - AttributeGroup::Def(_) => panic!("expected Ref got Def"), - AttributeGroup::Ref(r) => assert_eq!(r.ref_.as_str(), "part-name-text"), - }, - } - } - } -} diff --git a/gen/version-b/src/xsd/simple_type.rs b/gen/version-b/src/xsd/simple_type.rs deleted file mode 100644 index ddd744a7f..000000000 --- a/gen/version-b/src/xsd/simple_type.rs +++ /dev/null @@ -1,199 +0,0 @@ -use crate::error::Result; -use crate::xsd::annotation::Annotation; -use crate::xsd::constants::{ANNOTATION, LIST, NAME, RESTRICTION, SIMPLE_TYPE, UNION}; -use crate::xsd::id::{Id, Lineage, RootNodeType}; -use crate::xsd::list::List; -use crate::xsd::restriction::Restriction; -use crate::xsd::union::Union; -use crate::xsd::{name_attribute, Xsd}; - -#[derive(Clone, Debug)] -pub struct SimpleType { - pub id: Id, - pub name: String, - pub annotation: Option, - pub payload: Payload, -} - -#[derive(Clone, Debug)] -pub enum Payload { - Restriction(Restriction), - List(List), - Union(Union), -} - -impl SimpleType { - pub fn documentation(&self) -> String { - if let Some(annotation) = &self.annotation { - return annotation.documentation(); - } - "".to_owned() - } - - pub fn from_xml(node: &exile::Element, lineage: Lineage, xsd: &Xsd) -> Result { - check!(SIMPLE_TYPE, node, xsd)?; - let (id, lineage) = Id::make(lineage, node)?; - let mut annotation = None; - let mut payload = None; - for inner in node.children() { - let t = inner.name.as_str(); - payload = match t { - ANNOTATION => { - annotation = Some(Annotation::from_xml(inner, lineage.clone(), xsd)?); - continue; - } - RESTRICTION => Some(Payload::Restriction(Restriction::from_xml( - inner, - lineage.clone(), - xsd, - )?)), - LIST => Some(Payload::List(List::from_xml(inner, lineage.clone(), xsd)?)), - UNION => Some(Payload::Union(Union::from_xml( - inner, - lineage.clone(), - xsd, - )?)), - _ => { - return raise!("unexpected element name '{}'", t); - } - }; - } - let payload = payload.ok_or(make_err!("{} is incomplete", SIMPLE_TYPE))?; - Ok(SimpleType { - id, - name: name_attribute(node)?, - annotation, - payload, - }) - } -} - -#[test] -fn parse_enum() { - use super::restriction::Facet; - use crate::xsd::constants::*; - let xml_str = r#" - - - The above-below type is used to indicate whether one element appears above or below another element. - - - - - - "#; - let doc = exile::parse(xml_str).unwrap(); - let xml = doc.root(); - let want_index: u64 = 3; - let st = SimpleType::from_xml(&xml, Lineage::Index(want_index), &Xsd::new("xs")).unwrap(); - assert_eq!(st.id.index().unwrap(), want_index); - let got_id = st.id.to_string(); - let want_id = "simpleType:above-below".to_owned(); - assert_eq!(got_id, want_id); - let got_doc = st.documentation(); - let want_doc = "The above-below type is used to indicate whether one element appears above or below another element."; - assert_eq!(got_doc, want_doc); - match st.payload { - Payload::Restriction(r) => { - assert_eq!(r.facets.len(), 2); - match r.facets.get(0).unwrap() { - Facet::Enumeration(value) => { - assert_eq!(value.as_str(), "above"); - } - _ => panic!("expected '{}'", ENUMERATION), - } - match r.facets.get(1).unwrap() { - Facet::Enumeration(value) => { - assert_eq!(value.as_str(), "below"); - } - _ => panic!("expected '{}'", ENUMERATION), - } - } - _ => panic!("expected '{}'", RESTRICTION), - } -} - -#[test] -fn parse_numeric() { - use super::restriction::{Facet, Number}; - use crate::xsd::constants::*; - let xml_str = r#" - - - The midi-16 type is used to express MIDI 1.0 values that range from 1 to 16. - - - - - - "#; - let doc = exile::parse(xml_str).unwrap(); - let xml = doc.root(); - let want_index: u64 = 4; - let st = SimpleType::from_xml(&xml, Lineage::Index(want_index), &Xsd::new("xs")).unwrap(); - assert_eq!(st.id.index().unwrap(), want_index); - let got_id = st.id.to_string(); - let want_id = "simpleType:midi-16".to_owned(); - assert_eq!(got_id, want_id); - let got_doc = st.documentation(); - let want_doc = "The midi-16 type is used to express MIDI 1.0 values that range from 1 to 16."; - assert_eq!(got_doc, want_doc); - match st.payload { - Payload::Restriction(r) => { - assert_eq!(r.facets.len(), 2); - match r.facets.get(0).unwrap() { - Facet::MinInclusive(number) => match number { - Number::Integer(i) => assert_eq!(1, *i), - _ => panic!("expected integer"), - }, - _ => panic!("expected '{}'", MIN_INCLUSIVE), - } - match r.facets.get(1).unwrap() { - Facet::MaxInclusive(number) => match number { - Number::Integer(i) => assert_eq!(16, *i), - _ => panic!("expected integer"), - }, - _ => panic!("expected '{}'", MAX_INCLUSIVE), - } - } - _ => panic!("expected '{}'", RESTRICTION), - } -} - -#[test] -fn parse_pattern() { - use super::restriction::Facet; - use crate::xsd::constants::*; - let xml_str = r#" - - - blerp - - - - - "#; - let doc = exile::parse(xml_str).unwrap(); - let xml = doc.root(); - let want_index: u64 = 3; - let st = SimpleType::from_xml(&xml, Lineage::Index(want_index), &Xsd::new("xs")).unwrap(); - assert_eq!(st.id.index().unwrap(), want_index); - let got_id = st.id.to_string(); - let want_id = "simpleType:time-only".to_owned(); - assert_eq!(got_id, want_id); - let got_doc = st.documentation(); - let want_doc = "blerp"; - assert_eq!(got_doc, want_doc); - match st.payload { - Payload::Restriction(r) => { - assert_eq!(r.facets.len(), 1); - match r.facets.get(0).unwrap() { - Facet::Pattern(value) => { - assert_eq!(value.as_str(), "[1-9][0-9]*(, ?[1-9][0-9]*)*"); - } - _ => panic!("expected '{}'", PATTERN), - } - } - _ => panic!("expected '{}'", RESTRICTION), - } -} diff --git a/gen/version-b/src/xsd/union.rs b/gen/version-b/src/xsd/union.rs deleted file mode 100644 index e77bb2f19..000000000 --- a/gen/version-b/src/xsd/union.rs +++ /dev/null @@ -1,82 +0,0 @@ -use crate::error::Result; -use crate::xsd::annotation::Annotation; -use crate::xsd::constants::{ANNOTATION, MEMBER_TYPES, NAME, UNION}; -use crate::xsd::id::{Id, Lineage, RootNodeType}; -use crate::xsd::primitives::{BaseType, PrefixedParse}; -use crate::xsd::Xsd; - -#[derive(Clone, Debug)] -pub struct Union { - pub id: Id, - pub annotation: Option, - pub members: Vec, -} - -impl Union { - pub fn documentation(&self) -> String { - if let Some(annotation) = &self.annotation { - return annotation.documentation(); - } - return "".to_owned(); - } - - pub fn from_xml(node: &exile::Element, lineage: Lineage, xsd: &Xsd) -> Result { - check!(UNION, node, xsd)?; - let (id, lineage) = Id::make(lineage, node)?; - let mut items = Vec::new(); - let members = node - .attributes - .map() - .get(MEMBER_TYPES) - .ok_or_else(|| make_err!("'{}' attribute not found", MEMBER_TYPES))?; - for item in members.split(' ') { - if !item.is_empty() { - items.push(item.to_owned()); - } - } - let mut annotation = None; - for inner in node.children() { - let t = inner.name.as_str(); - if t == ANNOTATION { - annotation = Some(Annotation::from_xml(inner, lineage.clone(), xsd)?); - break; - } - } - let mut members = Vec::new(); - for item in &items { - let base_type = BaseType::parse_prefixed(item.as_str(), xsd.prefix.as_str())?; - members.push(base_type); - } - // TODO also parse in-line definitions of xs:simpleType - let u = Union { - id, - annotation, - members, - }; - Ok(u) - } -} - -// TODO fix test -#[test] -fn parse() { - let parent = crate::xsd::id::Id::new(crate::xsd::id::RootNodeType::Element, "foo".into()); - let lineage = Lineage::Parent(parent); - let xml_str = r#""#; - let doc = exile::parse(xml_str).unwrap(); - let xml = doc.root(); - let want_id = "element:foo:union:18365985102726890478".to_owned(); - let want_doc = ""; - let union = Union::from_xml(&xml, lineage, &Xsd::new("xs")).unwrap(); - let got_doc = union.documentation(); - assert_eq!(got_doc.as_str(), want_doc); - let got_id = format!("{}", union.id); - assert_eq!(got_id, want_id); - // let got_type = union.id.entry_type; - // assert_eq!(got_type, RootNodeType::Other(UNION.to_owned())); - let want_members = vec![ - BaseType::Decimal, - BaseType::Custom("css-font-size".to_owned()), - ]; - assert_eq!(union.members, want_members); -} diff --git a/gen/version-b/src/xsd/utils.rs b/gen/version-b/src/xsd/utils.rs deleted file mode 100644 index 98717a929..000000000 --- a/gen/version-b/src/xsd/utils.rs +++ /dev/null @@ -1,36 +0,0 @@ -#[macro_use] -use crate::error::Result; -use crate::xsd::Xsd; - -// expected: &str, node: &exile::Element, xsd: &Xsd -macro_rules! check { - ($expected:expr, $node:expr, $xsd:expr) => {{ - if let Some(ns) = &$node.namespace { - if ns.as_str() != $xsd.prefix() { - return raise!( - "expected namespace prefix '{}', got '{}'.", - $xsd.prefix(), - ns.as_str() - ); - } - } else { - return raise!("no namespace prefix, expected '{}'.", $xsd.prefix()); - }; - Ok(()) - } as crate::error::Result<()>}; -} - -// fn expect(expected: &str, node: &exile::Element, xsd: &Xsd) -> Result<()> { -// if let Some(ns) = &node.namespace { -// if ns.as_str() != xsd.prefix() { -// return raise!( -// "expected namespace prefix '{}', got '{}'.", -// xsd.prefix(), -// ns.as_str() -// ); -// } -// } else { -// return raise!("no namespace prefix, expected '{}'.", xsd.prefix()); -// }; -// Ok(()) -// } diff --git a/gen/version-b/tests/xsd.rs b/gen/version-b/tests/xsd.rs deleted file mode 100644 index 60233ee7f..000000000 --- a/gen/version-b/tests/xsd.rs +++ /dev/null @@ -1,9 +0,0 @@ -use libmxgen::generate::paths::Paths; -use libmxgen::xsd::Xsd; - -#[test] -fn xsd() { - let paths = Paths::default(); - let xsd = Xsd::load(&paths.xsd_3_0).unwrap(); - println!("{}", xsd); -} From ab6d8d5f776f4fa34cc43c4f5388de73649b156e Mon Sep 17 00:00:00 2001 From: Matthew James Briggs Date: Sun, 17 May 2026 14:47:04 +0200 Subject: [PATCH 2/3] =?UTF-8?q?bootstrap:=20initial=20codegen=20research?= =?UTF-8?q?=20=E2=80=93=20forensics,=20override=20design,=20eval=20scoring?= =?UTF-8?q?=20design?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pre-iteration research: codegen-forensics.md forensic analysis of mx/core patterns, gen-overrides.md override mechanism design, gen/experiment stubs (gen_attrs.py, gen_enums.py, gen_enum_members.py), and change-penalty.md eval scoring design. --- docs/ai/project/agenda.md | 104 +++++-- docs/ai/project/change-penalty.md | 245 ++++++++++++++++ docs/ai/project/gen-overrides.md | 186 ++++++++++++ docs/codegen-forensics.md | 436 +++++++++++++++++++++++++++++ gen/experiment/gen_attrs.py | 113 ++++++++ gen/experiment/gen_enum_members.py | 103 +++++++ gen/experiment/gen_enums.py | 88 ++++++ 7 files changed, 1254 insertions(+), 21 deletions(-) create mode 100644 docs/ai/project/change-penalty.md create mode 100644 docs/ai/project/gen-overrides.md create mode 100644 docs/codegen-forensics.md create mode 100644 gen/experiment/gen_attrs.py create mode 100644 gen/experiment/gen_enum_members.py create mode 100644 gen/experiment/gen_enums.py diff --git a/docs/ai/project/agenda.md b/docs/ai/project/agenda.md index ab896c72a..4508ef7de 100644 --- a/docs/ai/project/agenda.md +++ b/docs/ai/project/agenda.md @@ -2,30 +2,92 @@ This is the project plan for supporting MusicXML 4.0 -## Phase 0: Prepare for AI Development - -- [x] Create a Makefile -- [x] fix the line endind issues in markdown files like README.md -- [x] write build-and-ci-design.md -- [x] implement changes per build-and-ci-design.md -- [x] Change local dev workflow and CI workflow based on the changed ./build-and-ci-design.md file -- [x] Push to CI in PR 145 and iteratively refine any mistakes so that the ci yaml works correctly - (but we will fix lints and warnings locally) -- [x] In parallel fix lints and warnings until make fmt && make check && make test-all passes - locally -- [x] push the changes to PR 145 and monitor for passing CI -- [x] clean up the commits locally such that we have the originally desired commit sequence, i.e. - fixup the original commits so that they work -- [x] prompt the user for a force push to PR 145 when commits are clean -- [x] monitor PR 145 after the force push -- [ ] Properly instruct coding agents about how many C++ symbols are involved, especially in mxcore. - They need to use techniques such as sampling to understand the codebase (sample certain elements - at random, for exmple). They need some estimate of how long different build operations will take - on a normal laptop. +## Phase 0: Prepare for AI Development (DONE) ## Phase 1: Reverse Engineer Codegen -- [ ] Design a process by which the AI agent can iteratively work on the codegen problem +This is a difficult process in which we need to reverse engineer and write a codegen program that, +when we run it using the same/current MusicXML schema, regenerates what we now see in mx/core. + +We are not ready to work on MusicXML 4.0 yet. First we want to be able to reliably reproduce the +code we find in mx/core, such that running codegen on the current schema produces the minimal diff +possible to the generated code. + +First I want to design the rules and evaluation criteria for a "regenerated" mx/core. When the gen +program runs, it should output it's results on top of mx/core. The diff should be as small as +possible from the generated code, however, no cheating. Everything in musicxml.xsd must result in +generated code output. + +When evaluating a small diff, consider the following rubrick. We want to minimize CHANGE_PENALTY. +Change points are assigned, 1 per line (whether addition or deletion), multiplied by the following +factors: +- 1: whitespace anywhere +- 1.5: comment changes in `mx/core` +- 2: non-whitespace code changes in `mx/core/*.cpp` files +- 5: non-whitespace code changes in `mx/core/*.h` files +- 10: changes in `mx/impl` files +- FAIL (infinity): changes in `mx/api` files + +These multiply by a diff analysis and lead to a CHANGE_PENALTY score, less is better. If static +analysis of the codegen program reveals that it is skipping parts of MusicXML XSD, then the program +is disqualified, it failed. + +Another analysis is conducted on the codegen program itself for readability, human +comprehensability, separation of concerns, extensibility and soundness of design. For example, a +program with a bunch of if/else statements to deal with special conditions would fair worse than a +program that has a well designed mechanism for defining codegen overrides or rule exceptions. TODO: +determine what sort of analysis tools are available for this. Call it CODEGEN_PROGRAM_QUALITY. + +Codegen program language: open to discussion and choosing the best tool for the job. + +Now consider that more than one agent attempts to solve this codegen problem in parallel producing +different programs. They choose a language, then figure out how to generate mx/core from +MusicXML.xsd keeping the scoring rubric in mind. They must produce a program that generates code and +that passes the mx quality gates. At the end their program and it's output are scored by an +impartial agent. + +Once we have a couple of attempts at this, we take the best one and if it can still be improved, we +could repeat the process but this time using agents who are asked to improve the winning program. + +What do you think of this plan? Will it work? Would you be able to help me lock down the plan better +with the grill me skill should I choose to move forward? + +### Open Questions Requiring Grill-Me Sessions + +Each item below needs a `/grill-me` session before Phase 1 agent work begins. Each session should +produce a doc in `docs/ai/project/`. + +- [x] **Override mechanism** (`phase1-overrides.md`) - Are hand-coded exceptions to codegen rules + allowed? If so, what form do they take, and how does CODEGEN_PROGRAM_QUALITY penalize them? This + resolves the tension between "no cheating" and the known human choices in mx/core. + OUTPUT=./gen-overrides.md + +- [x] **CHANGE_PENALTY threshold** (`phase1-scoring-thresholds.md`) - What numeric score is "good + enough" to exit Phase 1 and move to Phase 2? Without a pass/fail threshold the phase has no exit + criterion. OUTPUT=./change-penalty.md + - Note from `gen-overrides.md`: the override investigation found `mx/core` has legacy + XSD-infidelity (the "FIX" category), e.g. 45 attribute structs silently omit the `color` + attribute the XSD declares. A faithful generator must emit it, producing a large but correct + diff. This session must give faithfulness precedence over raw diff size, or the threshold + rewards reproducing legacy bugs. See the FIX section and Consequences in `gen-overrides.md`. + +- [ ] **CODEGEN_PROGRAM_QUALITY criteria** (`phase1-quality-criteria.md`) - How is program quality + measured concretely? Static analysis tools, manual rubric, or both? The current plan has a TODO + here. OUTPUT=./codegen-program-quality.md + +- [ ] **Language constraints** (`phase1-language-constraints.md`) - Which languages are permitted + for competing agents? Leaving this fully open produces incomparable results and risks poor tool + choices. OUTPUT=./language-constraints.md + +- [ ] **Systematic-gap scoring** (`phase1-systematic-gaps.md`) - How does scoring handle a program + that is systematically correct for 95% of elements but misses one XSD pattern that appears 300 + times? The current rubric has no partial-credit mechanism. OUTPUT=./scoring-gap.md (idea, perhaps + this can be solved by assigning a very large score for getting something that passes mx quality + gates without skipping anything in MusicXML.xsd) + - Note from `gen-overrides.md`: the missing-`color` FIX (45 structs) is a concrete instance of + the inverse problem - a systematic gap that already exists in `mx/core`, where the *correct* + generator must add ~300 lines and the rubric as written penalizes it. Use this as the worked + example for the partial-credit / faithfulness-over-diff mechanism. ## Phase 2: Modernize or Improve the C++ diff --git a/docs/ai/project/change-penalty.md b/docs/ai/project/change-penalty.md new file mode 100644 index 000000000..f55acc4bf --- /dev/null +++ b/docs/ai/project/change-penalty.md @@ -0,0 +1,245 @@ +# CHANGE_PENALTY Threshold and Phase 1 Exit Criterion + +```text +Done. Wrote docs/ai/project/change-penalty.md and checked off the agenda item. + + What I studied + + Per /wake-up, I traced AGENTS.md -> docs/ai/project/AGENTS.md -> agenda.md -> gen-overrides.md -> build-and-ci-design.md, plus the WIP commit + f723d00a and gen/experiment/. The first Phase 1 grill question (override mechanism) is done. The next problem is the CHANGE_PENALTY threshold (next + unchecked item, OUTPUT=./change-penalty.md). I verified the central evidence in code, not just in the prior doc: AccidentalAttributes.h has no color + member while ArrowAttributes.h and 25 siblings carry Color color - the FIX inversion is real. + + The recommendation, in brief + + The doc's thesis is contrarian to how the agenda framed the question. "What number is good enough?" is the wrong question: + + 1. The raw-diff rubric is inverted. It ranks the cheating generator (hardcode "skip color in 45 structs", ~0 penalty) strictly above the faithful one + (emit color, ~225+ points at the 5x .h multiplier). Picking a threshold doesn't fix this - it just sets the price of the bug. + 2. Fix: score the unexplained residual, not the raw diff. Every differing line is attributed to a gen-overrides.md category + (RULE/EXC/SUBSTRATE/FIX/ANOMALY). Classified, justified lines score zero; only unclassified lines accrue penalty. FIX stops competing with cheating. + 3. Exit = four gates, not a band. No-skip (disqualifying), quality gates, 100% classification completeness, and residual penalty = 0 modulo a closed, + named allowance list. A tolerance band is itself a cheating surface across 113k lines. + 4. Separated two uses the agenda conflated: residual penalty ranks competitors; the four gates exit the phase. Unit of judgment is the distinct + root-cause defect (one bad ordering rule != thousands of points), with line-penalty as telemetry/tiebreaker. + 5. Flagged mx/impl at 10x as too lenient - any mx/impl diff from a core-only generator signals an interface regression; promoted it to + justify-or-fail. + + I drew the boundary with scoring-gap.md explicitly (it owns recurrence-counting; this doc owns the shared foundation) so the remaining grill docs + don't diverge or duplicate. + + Two open items you may want to weigh in on, since I made the calls unilaterally given no interactive session: + - Residual = 0 instead of a tolerance band. This is the strongest and most opinionated claim. It's defensible for a one-time generator, but it raises + the Phase 1 exit bar significantly versus the agenda's "good enough" framing. + - scoring-gap.md and change-penalty.md overlap heavily (the agenda's own notes put the FIX example in both). I kept them separate per your stated + structure but they could arguably be one doc. + +✻ Sautéed for 3m 48s + +※ recap: Goal: design Phase 1 scoring for the MusicXML codegen rewrite. I wrote docs/ai/project/change-penalty.md recommending + residual-after-classification scoring with four exit gates, and checked off the agenda item. Next: your review of the residual=0 decision. (disable + recaps in /config) +``` + +Resolves the second Phase 1 open question in `agenda.md`: what numeric score is "good enough" to +exit Phase 1. The short answer is that a generous numeric "good enough" is the wrong instrument. The +exit criterion is a conjunction of gates; the numeric penalty's job is to be driven to zero on the +*unexplained residual*, not to define a tolerance budget. This doc depends on the classification +taxonomy established in `gen-overrides.md` (RULE / EXC / SUBSTRATE / FIX / ANOMALY). + +## Context + +Two facts shape every decision here, both inherited from `gen-overrides.md`: + +- **4.0 codegen is a one-time run.** Phase 1 reproduces the current `mx/core` from the current + schema so the generator can be trusted before it is pointed at 4.0. The pass/fail bar exists to + certify that trust, not to protect a recurring build. +- **`mx/core` contains legacy XSD-infidelity (the FIX category).** A faithful generator must emit + code that differs from the checked-in source. The exit criterion must score that difference as + *correct*, or it certifies a generator that reproduces bugs. + +## The flaw in CHANGE_PENALTY as written + +The agenda computes penalty over the raw diff between regenerated output and checked-in `mx/core`: 1 +point per added or deleted line, multiplied (1 whitespace, 1.5 comment, 2 `core/*.cpp`, 5 +`core/*.h`, 10 `mx/impl`, FAIL for `mx/api`). Lower is better. + +Worked example, verified in code. `docs/musicxml.xsd` reaches the `color` attribute via +`print-style` for 71 complexTypes that have an attributes struct. 26 emit the field; 45 omit it. +`src/private/mx/core/elements/AccidentalAttributes.h` is a confirmed omission - it has no `color` +member, while `ArrowAttributes.h` and 25 others do. A faithful generator emits `color` in all 71. +That is roughly 45 added `.h` lines at the 5x multiplier (`~225 points`) plus the matching `.cpp` +accessor and stream lines at 2x, for one FIX. + +So the raw-diff rubric ranks the *unfaithful* generator - the one that hardcodes "skip color in +these 45 structs" - strictly above the faithful one. That hardcoded skip is precisely the cheating +the agenda forbids ("no cheating", "Everything in musicxml.xsd must result in generated code +output"). Any single numeric "good enough" threshold over the raw diff has this inversion built in. +Picking a number does not fix it; it sets the price of the bug. + +A second, structural flaw: the metric counts a modified line as delete + add (2 points) and a moved +block as N deletes + N adds. A single wrong ordering rule applied by an otherwise correct generator +reorders entire files and accrues penalty proportional to file size for what is one root-cause +defect. The raw metric punishes one mistake thousands of times. + +## The mechanism: penalty is computed over the unexplained residual + +CHANGE_PENALTY must not be computed over the raw diff. It is computed over the **residual** - the +diff that remains after every differing line is attributed to a category from `gen-overrides.md`. +The generator already takes a declarative overrides input; that same manifest is the ledger that +attributes diff lines: + +- **RULE-correct**: lines that match checked-in `mx/core`. Zero diff, zero penalty. +- **FIX**: lines that differ because the generator correctly emits XSD content `mx/core` never + emitted. Declared in the manifest, each entry validated against `docs/musicxml.xsd` by an + analyzer. Scored **zero**. A FIX whose declared XSD justification does not check out is not a FIX + \- it falls through to residual. +- **EXC**: lines produced by a justified slot reproducing a deliberate human choice. Scored zero + when the slot output matches the checked-in source; any delta is residual. +- **SUBSTRATE**: not generation output; out of diff scope by construction (namespace-derived, + analyzer-enforced per `gen-overrides.md`). +- **ANOMALY**: each anomaly carries a recorded decision (reproduce or correct). The resulting diff + is scored zero *because the decision is recorded and justified*, not because it is small. An + anomaly with no recorded decision falls to residual. +- **Residual**: every diff line with no valid classification. This, and only this, is what + CHANGE_PENALTY scores, using the agenda's multiplier table. + +This converts the metric from "size of the diff" to "size of the *unexplained* diff" and is the +concrete faithfulness-over-diff-size mechanism the agenda asks both this session and +`scoring-gap.md` to supply. FIX no longer competes with cheating: emitting `color` in 45 structs is +a declared, XSD-validated FIX worth zero; *not* emitting it is now the defect, because the missing +lines become unexplained residual against the faithful target. + +## The exit criterion: four gates, not one number + +Phase 1 exits when a generator passes all four. The first three are binary. The fourth carries the +number, and the number is small by design. + +**Gate A - No-skip (binary, already in the agenda).** Static analysis of the generator confirms +every `xs:element`, `xs:simpleType`, `xs:complexType`, `xs:attribute`, `xs:attributeGroup`, and +`xs:group` in `docs/musicxml.xsd` reaches a code-emitting path. Skipping disqualifies. The +scoring-gap note's "very large score for not skipping" is best realized as this hard gate, not as +points; a score, however large, is a budget, and a budget is a cheating surface. + +**Gate B - Quality gates (binary).** The regenerated tree passes +`make fmt && make check && make test-all` (test-all because the change touches +`src/private/mx/core/`). Non-negotiable and independent of any diff measurement. + +**Gate C - Classification completeness (binary).** 100% of diff lines are attributed to a category +above. An unclassified diff line is a defect, not a tolerated cost. This gate is what makes Gate D +safe: with no unclassified lines permitted, there is no budget to spend on unjustified deviation +spread thin across 1182 files. + +**Gate D - Residual target (numeric).** The residual penalty, computed with the agenda's multipliers +over only the unexplained residual, must be **zero**, with a single published, enumerated allowance +list for irreducible noise (see below). There is no generous "good enough" band. A nonzero tolerance +is itself the cheating surface this whole design removes: spread across a 113k-line tree it silently +funds exactly the legacy-bug reproduction the agenda warns about. + +### Why zero, and why an enumerated allowance instead of a band + +A tolerance band answers "how much unjustified wrongness do we accept?" The correct answer for a +one-time generator that becomes the new hand-maintained source is none - every nonzero diff line is +either explained (classified, zero penalty) or a defect (fix it or justify it). The allowance list +is not a band; it is a closed, named set of noise sources agreed in advance, each of which is then +itself zero: + +- Formatting is normalized away. `make fmt` applies the same pinned clang-format-18 Microsoft style + to both the regenerated output and the checked-in tree (the tree was reformatted in commit + 662c7ff9). Whitespace residual after `make fmt` is expected to be 0; if it is not, that is a + generator defect, not noise. +- The license banner (`// MusicXML Class Library` / copyright / MIT, verified as the first three + lines of `AccidentalAttributes.h`) is RULE-derivable and reproduced verbatim. There is no + historical "generated by" banner to reconstruct. +- Any other claimed-irreducible source must be added to this list by name with justification before + it is allowed, and the goal remains to drive it to a RULE that produces zero. + +If the first reverse-engineering attempt cannot reach zero residual, that is expected and is handled +by the ranking metric below - it does not lower Gate D. Phase 1 iterates (the agenda's "repeat the +process improving the winning program") until Gate D is met. Gate D is the exit bar; it is not the +within-iteration progress signal. + +## Two distinct uses the agenda conflates + +The agenda uses one metric for two jobs. They need different treatment. + +1. **Ranking competing generators** ("scored by an impartial agent ... take the best one"). Rank by + residual penalty (Gates A-C as prerequisites to be ranked at all). Ranking must use + residual-after-classification, never raw diff - otherwise the cheater that reproduces the + missing-`color` bug out-ranks the faithful generator, and the competition selects the wrong + winner to carry into the improvement round. Among generators with equal residual, rank by **fewer + distinct root-cause defects**, then by raw line-penalty as the final tiebreaker. + +2. **Exiting Phase 1** (the pass/fail this doc resolves). Gates A-D. This is not a ranking; it is a + certification that the winner is trustworthy to point at 4.0. + +The unit for ranking and for "is this defect-free" is the **distinct root-cause defect**, not the +line. One wrong ordering rule that reorders 40 files is one defect, not thousands of points. +Line-weighted penalty is retained only as telemetry while iterating and as the last tiebreaker. +Counting a systematic gap that recurs 300 times as one defect rather than 300x penalty is the +partial-credit problem owned by `scoring-gap.md`; this doc establishes the shared foundation +(residual-after-classification, defect-as-unit) and explicitly defers the recurrence-counting +mechanism there. The two docs must not diverge on the foundation. + +## Multiplier table review + +The agenda's table is mostly sound for scoring residual. Three adjustments: + +- **`mx/impl` at 10x is too lenient as a mere cost.** A core-only generator that produces any + `mx/impl` diff has changed a generated core API signature the conversion layer consumes (added + fields cannot break `mx/impl`; renamed or removed ones can). Treat any `mx/impl` residual as a + **Gate C / Gate D failure requiring explicit justification**, not a payable 10x cost. `mx/api` = + FAIL is correct and stays. +- **Modify = 2 points and move = 2N points stand**, but only for residual. Because residual excludes + classified lines and the unit of judgment is the defect, the double-count no longer punishes one + mistake thousands of times - it inflates the telemetry number for a single defect, which is + acceptable for a tiebreaker. +- **`.h` 5x vs `.cpp` 2x vs comment 1.5x vs whitespace 1x** are reasonable interface-weighted values + and need no change for residual scoring. + +## Recommendation summary + +1. Compute CHANGE_PENALTY over the **unexplained residual**, never the raw diff. Classified lines + (FIX, EXC, SUBSTRATE, recorded ANOMALY) score zero. +2. Phase 1 exits on the conjunction of **Gate A** (no-skip, disqualifying), **Gate B** + (`make fmt && make check && make test-all`), **Gate C** (100% diff lines classified), and **Gate + D** (residual penalty = 0 modulo a closed, named allowance list). +3. Replace the "good enough numeric band" question with "residual = 0"; a tolerance band is a + cheating surface on a 113k-line tree. +4. Use residual penalty to **rank** competing generators; use the four gates to **exit**. Make the + unit of both ranking and exit the distinct root-cause defect, with line-penalty as telemetry and + final tiebreaker only. +5. Promote `mx/impl` residual from a 10x cost to a justify-or-fail gate condition. + +## Boundary with the other open questions + +- `scoring-gap.md` (systematic-gap / partial credit): owns counting an N-times-recurring gap as one + defect. Inherits this doc's residual-after-classification foundation and defect-as-unit; must not + redefine them. +- `codegen-program-quality.md`: `CODEGEN_PROGRAM_QUALITY` judges the override mechanism's design + (per `gen-overrides.md`), independent of CHANGE_PENALTY. The two scores are orthogonal; a + generator can pass Gate D with a poorly designed override mechanism and still fail Phase 1 on + quality. Note the cross-dependency, do not merge the metrics. +- `language-constraints.md`: unaffected by this doc. + +## Method and evidence + +- Missing-`color` FIX verified directly: `grep` confirms no `color` member in + `src/private/mx/core/elements/AccidentalAttributes.h`; `Color color` present in + `ArrowAttributes.h` and 25 siblings. Counts (71 reach `color`, 26 emit, 45 omit) are from + `gen-overrides.md`, reproducible via the probes in `gen/experiment/`. +- Tree scale: `src/private/mx/core` is 1182 files and ~113k lines; the 5x `.h` multiplier over 45 + FIX additions (~225 points for one FIX) is the concrete inversion that forces + residual-after-classification rather than a tuned threshold. +- Formatting normalization assumption rests on `build-and-ci-design.md` (pinned clang-format-18, + Microsoft style, applied to `mx/core`) and the reformat in commit 662c7ff9; Gate D treats + post-`make fmt` whitespace residual as a defect, not noise, on that basis. + +## Deferred to Phase 1 implementation + +- The analyzer that validates each declared FIX against `docs/musicxml.xsd` (the mechanism that + makes FIX-scored-zero non-gameable) is a build task, not a design question. +- The exact diff tooling that attributes lines to manifest entries is an implementation choice; the + requirement is per-line attribution with no unclassified lines, not a specific tool. +- ANOMALY decisions (reproduce vs correct) are recorded per `gen-overrides.md`'s ANOMALY table; this + doc only requires that the decision exists and is justified for the line to score zero. diff --git a/docs/ai/project/gen-overrides.md b/docs/ai/project/gen-overrides.md new file mode 100644 index 000000000..a8b7a6a63 --- /dev/null +++ b/docs/ai/project/gen-overrides.md @@ -0,0 +1,186 @@ +# Codegen Override Mechanism + +Resolves the first Phase 1 open question in `agenda.md`: are hand-coded exceptions to codegen +rules allowed, what form do they take, and how does `CODEGEN_PROGRAM_QUALITY` treat them. The +design below is grounded in a catalog of the actual non-derivable points in `mx/core`, found +by deriving code from `docs/musicxml.xsd` and diffing against the checked-in source. + +## Context + +Two facts shape every decision here: + +- **4.0 codegen is a one-time run.** There is no recurring build to protect, so "hard-fail on + schema drift" is not the right tool. The output of the 4.0 run becomes the new + hand-maintained `mx/core`. +- **The spec is too large to eyeball.** The risk is not score-gaming. It is that an override + correct for MusicXML 3.x silently produces wrong code among thousands of 4.0 symbols, with + no human able to review all of it. + +## The mechanism + +**Overrides are a first-class declarative input to the generator**, not an afterthought: +`generator(musicxml.xsd, overrides) -> mx/core`. `CODEGEN_PROGRAM_QUALITY` judges the design +of the override *mechanism*, not the number of override entries. + +**Generality is the organizing axis.** A general rule is keyed on a structural condition +(collides with a C++ keyword, XSD type is extensible, name clashes with an element class). It +scales to 4.0's new symbols for free and needs zero per-symbol human attention. A named +per-symbol exception covers exactly one 3.x symbol, does not scale, and is one more thing a +human must re-check at 4.0 time. + +**The optimization target is minimizing the count of named per-symbol exceptions.** General +rules are effectively free. The rule is the default and the named exception is the last +resort: a named exception is admissible only with a justification that (a) no structural +condition can express the behavior and (b) records the 3.x schema assumption it freezes. That +recorded assumption is the entire 4.0 review checklist - the only realistic substitute for the +hard-fail that a one-time run rules out. `attributes` -> `Properties` is the canonical test: +it is attempted first as a general "XSD name collides with a C++ keyword/convention -> +deterministic rename" rule, not written as a one-off table row. + +**Irreducible code exceptions enter via snippet injection into named template slots.** The +element template declares slots (`parse_body`, `extra_private_methods`, `stream_contents`, +...). The declarative manifest binds a slot to a small verbatim `.cpp`/`.h` snippet file. The +generator renders a schema-derived skeleton and fills declared slots; it never names a symbol +in generator code. There are no whole-file escape hatches: even `Note.cpp` is brought into the +mechanism by decomposition into several small, individually justified slots +(`parse_note_choice`, `jit_allocation`, `add_beam_maxoccurs_guard`), not one mega-slot. + +**Anti-cheating is structural, not size-based:** + +1. The skeleton is a pure function of the XSD - class declaration, member layout (content + model + cardinality), accessors, `makeXxx` factories, `streamName`, standard interface + methods. A file whose skeleton is not schema-derived is a checked-in file and is + disqualified. +2. Slots carry only justified, irreducible bodies, decomposed small. +3. A slot is illegitimate if it has no valid justification, reproduces content a structural + rule could derive, or subsumes the skeleton. There is no hard per-slot size cap; + justification plus impartial reviewer is the gate, because an arbitrary cap only moves the + gaming to artificial slot-splitting. + +**Substrate is frozen and namespace-derived.** Foundational types the generator depends on +rather than emits: types resolving to an XSD built-in (`xs:string` -> `XsString`, `xs:token`, +`xs:ID`, `xs:anyURI`, `xs:decimal`, `xs:integer`), to an imported foreign namespace (XLink -> +`XlinkHref/Role/Title`; `xml:` -> `XmlLang/XmlSpace`), the generic numeric base machinery +(`Integer`, `IntRange`, `Decimal`, `DecimalRange`, `PreciseDecimal` - pure clamp/compare/store, +no MusicXML semantics), and runtime infrastructure (`ElementInterface`, `FromXElement.h`, +`ForwardDeclare` macros). Anything defined in the MusicXML target namespace is never +substrate: `Color` looks like a leaf scalar but `color` is a MusicXML `simpleType`, and its +hand-rolled ARGB/RGB parse freezes a 3.x assumption, so it stays generated-or-slotted. +Substrate membership is derived from namespace origin and enforced by static analysis, not +declared by the author; the analyzer rejects any MusicXML-namespace type that resolves to +substrate. "Everything in musicxml.xsd must result in generated output" stays intact because +substrate is the non-MusicXML foundation the schema imports. + +## Classification taxonomy + +Every non-derivable point in `mx/core` is exactly one of: + +- **RULE** - reducible to a structural rule; scales to 4.0 for free; the large majority. +- **EXC** - irreducible named per-symbol exception; needs a slot + justification + recorded + schema assumption. +- **SUBSTRATE** - frozen, not generation output; membership namespace-derived and + analyzer-enforced. +- **FIX** - XSD content `mx/core` never emitted. The faithful generator emits it and accepts + the diff. Treating a FIX as an override-to-preserve, to lower `CHANGE_PENALTY`, is the + cheating the agenda forbids. +- **ANOMALY** - a suspected legacy bug; verify against the XSD before deciding whether to + reproduce or correct it. + +EXC and FIX are handled oppositely: EXC preserves a deliberate human choice; FIX corrects a +legacy gap and *expects* a diff. The mechanism must therefore classify, not merely override. + +## Catalog of non-derivable points + +Found by deriving from `docs/musicxml.xsd` (5428 lines; 421 `xs:element`, 116 `xs:simpleType`, +179 `xs:complexType`) and diffing against `mx/core`. Quantitative claims below are measured, +not estimated. + +### What is RULE (the derivable bulk) + +The generator derives the following without per-symbol input. These scale to 4.0. + +| Concern | Rule | Coverage measured | +|---|---|---| +| Class name | PascalCase of XSD element/type name | - | +| `streamName` | verbatim XSD name | - | +| Enum class name | PascalCase; append `Enum` iff it collides with an element/complexType class name | 81 of 85 exact | +| Enum members | camelCase(value split on `-`/`_`/space); append `_` iff C++ keyword; `""` -> `emptystring`; numbered 0..n in XSD order | 77 of 81 exact | +| Numeric type collision suffix | `Value` (vs `Enum` for enums) | - | +| Attributes struct | complexType own attrs + transitive `attributeGroup` refs, flattened in document order; named after the complexType (or the element if the type is anonymous); shared by all elements of that type | 79 of 129 matched exact (rest are FIX-tainted, not rule failures) | +| Sequence content | ordered `Ptr my`; optional adds `bool myHas`; unbounded -> `Set`; order = XSD sequence order | - | +| Numeric scalars | ` : public IntRange`/`DecimalRange`, bounds from `min`/`maxInclusive` facets (unbounded if absent) | - | +| `measure`/`part` partwise vs timewise | same element name, two content models -> `Partwise*`/`Timewise*` split, both stream the bare name | - | +| Open-extension types | `Enum` enum + ``/`Value` wrapper (`enum + std::string myCustomValue`); inner enum gets `Enum` from collision with the wrapper | - | +| Imported `xml:` attributes | `xml:lang`/`xml:space` -> `XmlLang lang;`/`XmlSpace space;` (SUBSTRATE boundary) | - | +| `xs:group` wrapper classes | `*Group` class with empty `streamName` (transparent wrapper); parent streams its contents | all `*Group` except real elements `Group`/`PartGroup` and the 1 `LayoutGroup` anomaly | +| Document/PI/conversion infrastructure | `Document`, `DocumentHeader`, `ProcessingInstruction`, `ScoreConversions` - top-level machinery and the `XDoc`/ezxml bridge | SUBSTRATE (not MusicXML schema content) | + +### EXC - irreducible named exceptions + +This is the complete irreducible set. It is small and bounded. + +| XSD symbol | C++ artifact | Special handling | Frozen 3.x assumption to record | +|---|---|---|---| +| `attributes` (complexType/element) | `Properties` class, `streamName` "attributes" | renamed; collides with the `Attributes` struct naming convention | `attributes` is the only element whose name collides with the attributes-struct convention | +| `accidental-value`/`accidental` | `Accidental.cpp` remaps `"double-flat"` -> `"flat-flat"` + logs | semantic error-tolerance | `accidental-value` enumeration excludes `double-flat` in 3.x | +| `metronome-relation` | `MetronomeRelation` ctor hardcodes `myValue("equals")`; `setValue` neutered | value frozen | `metronome-relation` enumeration == {`equals`} | +| `dynamics` | `setAttributes` by const-ref value; hand-written `streamContents` emits child tags | non-standard setter + self-serialized child XML | `dynamics` content model is the fixed mark set + `other-dynamics` | +| `note`, `full-note`, music-data group, `measure` (partwise) | `MX_JIT_ALLOCATE`/`MX_MUTEX` lazy child allocation | performance choice, no XSD source | none (performance hint, not a schema fact) | +| `distance-type`, `line-width-type`, `mode` | enum member lists | values mined from `xs:documentation` prose; the schema has no `xs:enumeration` | the value list is the 3.x doc-prose enumeration | +| `note-type-value` | `NoteTypeValue` members | digit-leading values hand-spelled to English (`1024th` -> `oneThousandTwentyFourth`) | the digit-to-English value mapping | +| instrument-sound list | `PlaybackSound.h` X-macro, not the standard enum suite | different enum codegen path | the sound list contents | +| `color`, `comma-separated-text`, `number-or-normal`, `positive-integer-or-empty`, `yes-no-number`, `font-size`, date/time types | `Color`, `CommaSeparated*`, `NumberOrNormal`, `PositiveIntegerOrEmpty`, `YesNoNumber`, `FontSize`, `Date`, `TimeOnly`, `EndingNumber` | bespoke C++ shapes (pImpl, custom parse), not the generic range pattern | each type's lexical space per its 3.x restriction | + +### FIX - legacy infidelity the faithful generator must correct + +`mx/core` does not faithfully represent the XSD attribute model. These are bugs to fix, not +overrides to preserve. + +| XSD symbol | Gap | Measured | +|---|---|---| +| `color` attribute reachable via `print-style` | struct omits the `color` field non-uniformly | 71 complexTypes reach `color` and have a struct; 26 emit it; **45 omit it** (`AccidentalAttributes` confirmed) | +| `text-formatting` `dir`, `valign` | fields omitted in some structs | - | +| required-attribute error string | 46 `.cpp` hardcode `'number' is a required attribute` regardless of the actual attribute | 46 files | + +### ANOMALY - verify against the XSD before reproducing + +| Symbol | Suspected issue | +|---|---| +| `LayoutGroup` | streams `"work"`; the sole `*Group` with an erroneous non-empty `streamName` (matches the forensics misnamed-group-script finding) | +| `*Choice` inner `enum class Choice` start value | inconsistent with no semantic significance: 15 start at `1` (`ArticulationsChoice`, `BendChoice`, `CreditChoice`, `EncodingChoice`, `FullNoteTypeChoice`, `HarmonicInfoChoice`, `HarmonicTypeChoice`, `LyricTextChoice`, `MusicDataChoice`, `NotationsChoice`, `NoteChoice`, `OrnamentsChoice`, `PercussionChoice`, `SoloOrEnsembleChoice`, `TechnicalChoice`), 6 start at `0`. Normalize to one convention | +| `note-type-value` | hand-spelled value contains a typo: `twoHundredFifthySixth` ("Fifthy") | +| `DocumentChoice` | `DocumentSpec.h` uses old-style `enum`, not `enum class` | +| `PositiveDivisionsValue` vs `PositiveDivisions` vs `DivisionsValue` | redundant DecimalRange subclasses; one carries `/// TODO` | +| `EmptyPrintObjectStyleAlignAttributes` | only `*Attributes` placed in `core/` not `elements/`; criterion unclear | +| wrapper suffix (`DistanceType` vs `DynamicsValue` vs `LineWidthType` vs `ModeValue`) | inconsistent `Type`/`Value` suffix with no derivable reason | +| `dynamics` choice-of-empties -> enum collapse | confirm the structural-collapse rule generalizes rather than being a one-off | +| `articulations`/`encoding`/`notehead-text`/`technical` `*Choice` | confirm streamName-of-parent vs the empty-streamName choice pattern | + +## Consequences for the wider plan + +- **The mechanism must classify, not just override.** EXC and FIX require opposite treatment. + A mechanism that cannot express "this delta is a FIX, score it as correct" forces an agent + to either cheat (preserve the bug) or absorb an unfair `CHANGE_PENALTY`. +- **`change-penalty.md` and `scoring-gap.md` must give faithfulness precedence over diff + size.** The missing-`color` case is concrete proof: ~45 structs of correct `.h` additions + (5x multiplier) plus `.cpp` would lose under the rubric as written, which would reward + reproducing a legacy bug. This finding belongs in those two grill sessions. +- **An EXC's justification must record its frozen 3.x schema assumption** (see the EXC table's + last column). That column is the 4.0 reviewer's checklist. + +## Method and scope + +Derivation probes live in `gen/experiment/` (Python, stdlib `xml.etree`, chosen for +zero-dependency iteration in this investigation; the production generator language is a +separate Phase 1 question and is not decided here). Each probe derives one slice from the XSD +and diffs against `mx/core`; the measured counts above are reproducible by re-running them. + +All slices have been probed: enum names, enum members, attributes structs, element content +models, numeric scalars, choice classes, group classes, the bespoke `core/` scalars, and +document/conversion infrastructure. After `FIX` emerged no further category appeared, and the +later slices produced only further instances of existing categories, now enumerated in the +tables above (the 21 `*Choice` start-value split, the sole `LayoutGroup` group anomaly, the 10 +bespoke scalars, the infrastructure SUBSTRATE set). The catalog is both category-complete and +instance-complete for the override-mechanism decision; the ANOMALY rows marked "confirm" are +deliberately left as verification tasks for the Phase 1 implementation, not open design +questions. diff --git a/docs/codegen-forensics.md b/docs/codegen-forensics.md new file mode 100644 index 000000000..cab45076f --- /dev/null +++ b/docs/codegen-forensics.md @@ -0,0 +1,436 @@ +# Codegen Forensics + +This document records what we learned by statically analyzing (a) the historical Ruby codegen +scripts in `gen/version-a/` and (b) the C++ output they produced in `src/private/mx/core/`. The goal +is to understand what a new generator must reproduce, what was bespoke human judgment, and where the +original process had gaps. + +* * * + +## Part 1: Ruby Pipeline Analysis (`gen/version-a/`) + +### Pipeline Overview + +The pipeline was **not** a clean XSD-to-C++ pipeline. It operated in four historical phases with +significant human intervention between each, and it cannot be re-run today. + +**Phase 1 - Original hand-built monolith (lost):** A single massive `Elements.h` (`~37,000+` lines) +and matching `Elements.cpp` contained every class declaration and definition. Brute force, +iteratively generated with Ruby scripts that are lost. + +**Phase 2 - Splitting:** `writeHFiles.rb` and `writeElementsCppFiles.rb` read the monolithic files +and emitted one `.h`/`.cpp` pair per class into `src/mx/core/elements/`. The split was driven by +line-range detection via `parseElementsH.rb` (scanned for `class X : public ElementInterface` and +matching `};`) and `parseElementsCpp.rb` (scanned for `ClassName::method` patterns, hardcoded +terminal line 37340). + +**Phase 3 - Patching `fromXElement`:** `fromXElement.rb` and `attributes.rb`/`attributesLoop.rb` +read the split files and surgically inserted `fromXElement`/`fromXElementImpl` method bodies. The 14 +`*Group.rb` scripts each generated a group element's `fromXElement` body to stdout; those snippets +were copy-pasted into the relevant `.cpp` files by hand. + +**Phase 4 - Ad-hoc maintenance:** `adjustElementsH.rb`, `adjustElementsCpp.rb`, +`findFilesWithBadCopyright.rb`, `smuflHeader.rb`, `parseElementsHOrder.rb` were run one-off as +needed. + +The `mxdeploy*.rb` scripts are unrelated to codegen - they built iOS/macOS frameworks for a +different app. + +### XSD Parsing + +`parseXsd.rb` is a stub. It uses Ruby's REXML to dump `xs:element` names from `docs/musicxml.xsd` to +stdout and does nothing else. It was never integrated into the emit pipeline. The scripts that +generated the monolithic Elements.h/cpp have been lost. + +### Code Emission + +**Header splitting (`writeHFiles.rb`):** +- Detects class boundaries by scanning for `class X : public ElementInterface` / + `struct X : public AttributesInterface` and matching `};` +- Per-class `.h` file: copyright banner, `#pragma once`, conditional includes (only Decimals.h, + Enums.h, Integers.h, Strings.h), forward declarations, then the class body verbatim +- Include selection uses `isSymbolFound.rb`: regex `(\s#{symbol}\s|\s#{symbol}&)` - only matches + tokens surrounded by whitespace or followed by `&`. Misses tokens in template args, after `*`, + after `(`, or at line start + +**CPP splitting (`writeElementsCppFiles.rb`):** +- Groups function bodies by class name (scanned from `ClassName::methodName` patterns) +- Hardcodes line 37340 as the end of `Elements.cpp` + +**Attributes `fromXElement` (`attributes.rb`, `attributesLoop.rb`):** +- Parses `public:` section of a split `.h` to build member list +- Derives XML attribute name from camelCase member name via + `name.split(/([[:upper:]][[:lower:]]*)/).join("-").downcase` +- Pairs `has___` booleans with members to determine optionality +- Emits `parseAttribute(...)` calls; enum members get `&parseEnumType` function pointer +- `attributesLoop.rb` batch-applies to all `*Attributes.h` files + +**Element `fromXElement` (`fromXElement.rb`):** +- Classifies members by naming convention: `myAttributes`, `myHas___` flag, `___Set`, + `___GroupPtr/Set`, `___ChoicePtr/Set` +- Emits five body patterns based on classification: + 1. Empty element (no members): `return true;` + 2. Attributes only: delegate to `myAttributes->fromXElement(...)` + 3. Value + attributes: parse attributes, then `myValue.parse(xelement.getValue())` + 4. Value only: `myValue.parse(xelement.getValue())` + 5. Full element: iterate child elements, dispatch on element name string + +**Group scripts (`*Group.rb`):** +- 14 standalone scripts, each nearly identical, differing only in class name and members array +- Each member is hand-enumerated with XML element name string, C++ class name, and cardinality + (`required`, `optional`, or `collection`) +- All write to stdout; copy-pasted into `.cpp` files by hand + +### Bespoke Touches in the Ruby Scripts + +1. **`Properties` class name override.** The XSD element is named `attributes`, which clashes with + the C++ keyword and member naming conventions. The C++ class is `Properties`; its `streamName` + outputs `"attributes"`. This is the only element where C++ class name does not match XSD element + name. Noted in `todo.txt`. + +2. **`EditorialVoiceDirectionGroup` manual registration.** Added by hand to `listElementClasses.rb` + (`element_classes << "EditorialVoiceDirectionGroup"`) because it doesn't inherit from + `ElementInterface` in the way the parser could auto-detect. + +3. **Hardcoded line 37340** in `parseElementsCpp.rb` as the last line of the monolithic + `Elements.cpp`. Stale if the file ever changed. + +4. **Six hardcoded "special classes"** in `listSpecialClasses.rb`: `Color`, `Date`, `FontSize`, + `NumberOrNormal`, `PositiveIntegerOrEmpty`, `YesNoNumber`. These live in `core/` not `elements/` + and required manual registration. `writeHFiles.rb` also hardcodes + `EmptyPrintObjectStyleAlignAttributes`, `Document`, `DocumentPartwise`, `DocumentTimewise`, + `DocumentHeader`, `DocumentSpec` with standalone include calls. + +5. **`listDecimals.rb` manual fixups.** `kDefaultPrecision` and `kNonZeroAmount` are manually + appended after parsing `Decimals.h`; `"impl"` is manually deleted. + +6. **Required-attribute error message bug.** In `attributes.rb`, the required-attribute error is + hardcoded as `"'number' is a required attribute but was not found"` regardless of which attribute + is actually required. This bug propagates to all attributes structs. + +7. **Misnamed group scripts.** `midiDeviceInstrumentGroup.rb` generates `NormalTypeNormalDotGroup` + (not a MIDI group). `layoutGroup.rb` generates `MetronomeRelationGroup`. + `displayStepOctaveGroup.rb` generates `EditorialGroup`. These were copy-pasted and filenames were + never updated. + +8. **`cueNoteGroup.rb` placeholder bug.** `FullNoteGroup` (a group, not a leaf element) has no XSD + element name; the script inserts the string `"TODO fix this"` as its element name, generating + `if( elementName == "TODO fix this" )` - which never matches. + +9. **Group scripts output to stdout only.** No script automatically writes a group's `fromXElement` + body to disk. All group `fromXElement` bodies were copy-pasted by hand. + +10. **`elementsHUsingFile.rb` was a one-time op.** Creates C++ `using` alias headers for cases where + multiple XSD names map to the same C++ class. The call sites in `writeHFiles.rb` are commented + out. + +11. **`MetronomeRelation` frozen value.** Per `todo.txt`, the only valid MusicXML value is + `"equals"`, so `setValue` is commented out and the constructor hardcodes `myValue("equals")`. + +12. **SMUFL glyph map** (`smuflHeader.rb`) generated from `data/smufl/glyphnames.json`, producing + `src/mx/impl/SMUFLGlyphMap.h`. Entirely outside the MusicXML XSD. + +13. **`isSymbolFound` regex fragility.** Matches only `SomeType` or ` SomeType&`. Tokens in + ``, after `*`, after `(`, or at line start are missed - potentially producing missing + includes or forward declarations. + +14. **Scripts reference stale paths.** All scripts reference `../../src/mx/core/`; the current path + is `src/private/mx/core/`. Scripts cannot be re-run without path fixes and the absent monolithic + input files. + +### Gaps / Unknowns + +- The scripts which produced the original monolithic `Elements.h` are lost. +- 10 group classes have no corresponding group script (some correspond to the misnamed scripts + listed above; others are simply absent). +- How `*Choice` classes and complex groups were bootstrapped in the monolith is unknown. +- `addStubs.rb` is 0 bytes; its intended purpose is unknown. +- `ElementsOrder.xlsx` is binary; it appears to have established class declaration ordering in the + monolith, but its content cannot be statically analyzed. +- `adjustElementsCpp.rb` produces a `.replace` file; whether it was ever used to overwrite the + original is unknown. +- The exact script run order is undocumented; there is no master driver script. + +* * * + +## Part 2: `mx/core` Code Analysis + +### Type Taxonomy + +**Primitive / scalar types** (`src/private/mx/core/*.h`, not in `elements/`): + +| Category | Examples | +|-------------------|------------------------------------------------------------------------------| +| String wrappers | `XsString`, `XsToken`, `XsID`, `XsIDREF`, `XsNMToken`, `XsAnyUri` | +| Integer types | `Integer` -> `IntRange` -> `BeamLevel`, `OctaveValue`, `Midi128`, etc. (~15) | +| Decimal types | `Decimal` -> `DecimalRange` -> `TenthsValue`, `Percent`, etc. (~10) | +| Union types | `FontSize` (`Decimal`) | +| pImpl union types | `NumberOrNormal`, `PositiveIntegerOrEmpty` | +| Complex scalars | `Color` (ARGB/RGB, custom parse/serialize), `CommaSeparatedText`, | +| | `CommaSeparatedListOfPositiveIntegers` | +| Type aliases | `TimeOnly`, `EndingNumber`, `XlinkHref`, `XlinkRole`, `XlinkTitle` | + +**Enums** (`Enums.h`, `EnumsBuiltin.h`): + +89 total (85 + 4 builtins). Each has `parse`, `tryParse` (returns `std::optional`), +`toString`, `toStream`, `operator<<`. Builtins (`XlinkType`, `XmlSpace`, `XlinkActuate`, +`XlinkShow`) lack `tryParse`. + +Suffix rules: +- No suffix (47): XSD type name has no C++ collision (`AboveBelow`, `CssFontSize`, `YesNo`). +- `Enum` suffix (23): XSD type name collides with an element class name (`BarStyleEnum`, + `DynamicsEnum`, `StepEnum`). +- `Value` suffix (15): XSD extensible/open type (`BeamValue`, `AccidentalValue`, `BeaterValue`). +- 4 "open extension" wrapper classes: wrap an `enum class` + `std::string myCustomValue` for + `other-*` values (`DistanceType`, `DynamicsValue`, `LineWidthType`, `ModeValue`). + +**Element classes** (`elements/`, 1182 files = 591 pairs): + +| Subcategory | Count (approx) | Notes | +|---------------------------|----------------|-----------------------------------------| +| `*Attributes` structs | 174 pairs | One per element that has XSD attributes | +| `*Choice` classes | 21 pairs | XSD `xs:choice` constructs | +| `*Group` classes | 24 pairs | XSD `xs:group` named groups | +| Leaf / container elements | ~372 pairs | Normal element classes | + +**Infrastructure** (`core/` non-element headers): `ElementInterface`, `AttributesInterface`, +`ForwardDeclare.h` macros, `FromXElement.h` template helpers, `Document`, `DocumentSpec`, +`ScoreConversions`, `ProcessingInstruction`, `EmptyPrintObjectStyleAlignAttributes`. + +### Standard Element Template + +Every "leaf element with a value" follows this exact pattern: + +**Header:** +```cpp +MX_FORWARD_DECLARE_ATTRIBUTES(XxxAttributes) // if element has attributes +MX_FORWARD_DECLARE_ELEMENT(ClassName) + +inline ClassNamePtr makeClassName() { ... } +inline ClassNamePtr makeClassName(const ValueType&) { ... } +inline ClassNamePtr makeClassName(ValueType&&) { ... } + +class ClassName : public ElementInterface { +public: + ClassName(); + ClassName(const ValueType& value); + virtual bool hasAttributes() const; + virtual bool hasContents() const; + virtual std::ostream& streamAttributes(std::ostream& os) const; + virtual std::ostream& streamName(std::ostream& os) const; + virtual std::ostream& streamContents(std::ostream& os, int indentLevel, + bool& isOneLineOnly) const; + XxxAttributesPtr getAttributes() const; + void setAttributes(const XxxAttributesPtr& attributes); + ValueType getValue() const; + void setValue(const ValueType& value); +private: + virtual bool fromXElementImpl(std::ostream& message, ::ezxml::XElement& xelement); +private: + ValueType myValue; + XxxAttributesPtr myAttributes; +}; +``` + +**Attributes struct:** +```cpp +struct XxxAttributes : public AttributesInterface { + XxxAttributes(); + virtual bool hasValues() const; + virtual std::ostream& toStream(std::ostream& os) const; + Type1 field1; bool hasField1; + Type2 field2; bool hasField2; +private: + virtual bool fromXElementImpl(std::ostream& message, ::ezxml::XElement& xelement); +}; +``` + +Constructor initializes all `has*` to `false`. `hasValues()` is OR of all `has*` flags. `toStream` +calls `streamAttribute(os, field, "xsd-attr-name", hasField)` per attribute. `fromXElementImpl` +iterates `xelement.attributesBegin()..End()` with `if (parseAttribute(...)) continue;` chains; +enum-typed attributes pass a `&parseXxx` pointer. + +### Variance Map + +| Aspect | How it varies | XSD source | +|----------------------------|-------------------------------------------------------------|-------------------------| +| Class name | PascalCase of XSD element name | `xs:element name=""` | +| `streamName` string | Verbatim XSD kebab-case name | `xs:element name=""` | +| Value type | enum, XsString, XsToken, Integer/Decimal subclass, or none | `simpleType`/content | +| `hasContents()` | `true` if text content or children; `false` if empty | Content model | +| Attributes struct | Own `XxxAttributes` pair or shared `EmptyXxx` from `core/` | Attribute group | +| `makeXxx(value)` overloads | Present only if element has a value type | same | +| Child accessors | See cardinality table below | `minOccurs`/`maxOccurs` | +| `fromXElementImpl` | `importElement(...)` required; sets `myHasXxx` for optional | Content model | + +**Child accessor pattern by cardinality:** + +- `min=1, max=1` (required): member `ChildPtr myChild;`, accessors `getChild()` / `setChild()`. +- `min=0, max=1` (optional): member `ChildPtr myChild; bool myHasChild;`, accessors `getChild()` / + `setChild()` / `getHasChild()` / `setHasChild(bool)`. +- `max=unbounded` (set): member `ChildSet myChildSet;`, accessors `getChildSet()` / `addChild()` / + `removeChild(iter)` / `clearChildSet()`. + +For `min=1, max=unbounded`: pre-populated with one default instance; `clearChildSet()` re-adds one; +`removeChild()` refuses to erase the last item. + +**Group elements:** `streamName` returns empty string (no XML tag). `hasAttributes()` returns +`false`. They are transparent wrappers for XSD named groups. + +**Choice elements:** Hold an inner `enum class Choice { ... }` (values start at 0 in some, 1 in +others - inconsistent). All alternatives are pre-allocated in the constructor. `streamContents` +switches on `myChoice`. `fromXElementImpl` dispatches on `xelement.getName()`. + +### Naming Conventions + +**XSD element name -> C++ class name:** kebab-case to PascalCase. `score-partwise` -> +`ScorePartwise`, `time-modification` -> `TimeModification`. + +**Member variable prefix:** `my` for all members: `myValue`, `myAttributes`, `myHasChild`. + +**Typedef pattern (generated by `MX_FORWARD_DECLARE_ELEMENT`):** `ClassNamePtr`, `ClassNameUPtr`, +`ClassNameSet`, `ClassNameSetIter`, `ClassNameSetIterConst`. + +**Factory functions:** `makeClassName()`, `makeClassName(const T&)`, `makeClassName(T&&)` as inline +free functions in the header. + +**XSD attribute name -> C++ field name:** kebab-case to camelCase. `default-x` -> `defaultX`, +`font-family` -> `fontFamily`. Presence flag: `has` + PascalCase: `hasDefaultX`, `hasFontFamily`. + +**Enum type suffix disambiguation:** +- No suffix when the XSD type name has no class-name collision. +- `Enum` suffix when a class with the same PascalCase name also exists (e.g., `BarStyle` element -> + type becomes `BarStyleEnum`). +- `Value` suffix when the XSD type is extensible / ends in `-value`. + +**Enum value C++ names:** PascalCase from the XSD string. Reserved words get a trailing `_`: +`continue_`, `double_`, `short_`, `new_`, `default_`. + +**XML string literals in `streamName` / `streamAttribute`:** always the original XSD kebab-case +string verbatim. + +### Sequence vs. Choice vs. Group + +- **`xs:sequence`:** child members are declared in order on the class. `streamContents` outputs them + in sequence with newlines between. `fromXElementImpl` uses `importElement(...)` template or manual + `if (elementName == "xxx")` dispatch. +- **`xs:choice`:** generates a `*Choice` class with inner `enum class Choice`. All alternatives are + pre-allocated. `streamContents` switches on `myChoice`. Some choices implement `fromXElementImpl` + by dispatching on `xelement.getName()`; others use `MX_FROM_XELEMENT_UNUSED` when the parent + handles dispatch. +- **`xs:group` (named groups):** generates `*Group` class. `streamName` returns empty string. Parent + streams the group's contents directly via `group->streamContents(...)`. + +### Bespoke and Anomalous Items + +**`Properties` class** (`elements/Properties.h`): C++ class name is `Properties`; `streamName` +outputs `"attributes"`. Only element where class name does not match XSD element name. The XSD +element name `attributes` would clash with C++ keywords and naming conventions. + +**`Accidental.cpp`**: Hand-written error tolerance: if the parsed value is `"double-flat"` (not +valid in MusicXML 3.0), it is silently remapped to `"flat-flat"` with a log message. Not derivable +from the XSD. + +**`Dynamics.h/.cpp`**: Two structural deviations. (1) `setAttributes` takes +`const DynamicsAttributes& attributes` by const-ref value rather than the universal +`const DynamicsAttributesPtr&` pointer pattern. (2) `streamContents` hand-writes inner XML +sub-elements (``, `text`), breaking the standard "element text += `os << myValue`" pattern. `fromXElementImpl` reads `xelement.begin()->getName()` to reconstruct +the dynamic mark from a child element name. The only element that self-serializes child tags inside +`streamContents`. + +**`Note.h/.cpp`**: The most complex element. Three private parse helpers: `parseNoteChoice`, +`parseFullNoteGroup`, `parseEditorialVoiceGroup`. Large hand-written `fromXElementImpl`. Optional +children use JIT allocation with `MX_MUTEX`/`MX_LOCK`/ `MX_JIT_ALLOCATE` macros and `mutable` +members. `addBeam` enforces `maxOccurs=8` with a size guard (the only finite-`maxOccurs` enforcement +anywhere). + +**JIT-allocated elements** (`MX_MUTEX`/`MX_LOCK`/`MX_JIT_ALLOCATE`): `Note`, `MusicDataChoice`, +`FullNoteGroup`, `FullNoteTypeChoice`, `PartwiseMeasure`. No clear structural rule separates these +from other complex elements that pre-allocate. Likely applied manually where profiling showed +allocation cost. + +**`MX_FROM_XELEMENT_UNUSED` elements:** `NoteChoice`, `KeyChoice`, `EditorialGroup` (and possibly +others). These are parsed by their parent elements rather than independently. + +**`ScorePartwise.cpp`**: `fromXElementImpl` explicitly checks child element names to skip +header-group elements in the `` loop, delegating to `myScoreHeaderGroup->fromXElement(...)`. +Hand-written cross-delegation logic. + +**`EmptyPrintObjectStyleAlignAttributes.h`** (in `core/`, not `elements/`): Only attributes struct +at the `core/` level. Declares `fromXElementImpl` as `public` rather than `private` - the sole +inconsistency of this kind across all attributes structs. + +**`PlaybackSound.h`**: Uses X-macro technique (`Enum.h` utility) rather than the hand-written +`if`/`else` chains used in `Enums.h`. Generates `toString`/`fromString` but not the full +`parse`/`tryParse`/`operator<<`/`toStream` suite the other enums have. Likely added later when the +instrument sound list grew too large for manual maintenance. + +**`DocumentSpec.h`**: Defines `enum DocumentChoice` (old-style, not `enum class`) alongside two +`enum class` definitions. Inconsistent with the rest of the codebase. + +**`PositiveDivisionsValue`** in `Decimals.h`: Marked with +`/// TODO - this needs to be properly generated`. Appears to be an incomplete or redundant type +duplicating `PositiveDivisions`. + +**`TupletReader.h`**: Empty file (1 line). No `.cpp`. Dead placeholder. + +**`AttributesIterface.h`** (note typo: `Iterface`): Stub struct with no fields, no `.cpp`. Used only +in `Elements.h`. Appears to be an unused stub with a typo in the name. + +**`Choice` enum starting values:** Inner `enum class Choice` starts at 0 in some choice classes and +1 in others. The inconsistency has no apparent semantic significance. + +### Gaps and Open Questions + +1. **Enum suffix selection** (`Enum` vs. `Value` vs. no suffix) requires collision detection against + the full set of element class names. A new generator must build that set first. + +2. **`EmptyPrintObjectStyleAlignAttributes` placement** in `core/` vs. `elements/` has no clear + structural criterion. May simply have been promoted to `core/` because multiple elements share it + via attribute groups. + +3. **JIT allocation trigger**: Which elements use `MX_JIT_ALLOCATE` vs. pre-allocate is not + derivable from the XSD. Treat pre-allocation as the default; JIT allocation can be applied + manually to performance-critical paths. + +4. **`MX_FROM_XELEMENT_UNUSED` application**: Which groups and choices delegate to their parent for + parsing is not fully derivable from the XSD. Groups generally do; some choices do. + +5. **`PlaybackSound` X-macro pattern**: Needs a separate codegen path or manual treatment in a new + generator. + +6. **`PositiveDivisionsValue`** relationship to `PositiveDivisions` needs XSD verification before a + new generator handles it. + +7. **`Note::addBeam` maxOccurs=8 guard**: The only enforced finite `maxOccurs > 1`. Whether a new + generator should emit such guards generally needs a policy decision. + +8. **Shared `EmptyXxx` attribute structs**: Multiple elements share one struct (e.g., + `EmptyPlacementAttributes`). XSD uses attribute groups for this. The mapping from attribute group + -> shared struct needs explicit handling in a new generator. + +* * * + +## Summary: What a New Generator Must Handle + +| Concern | Derivable from XSD? | Notes | +|-------------------------------------------|------------------------|-----------------------------------------------------------| +| Class names (kebab -> PascalCase) | Yes | | +| XML string literals (`streamName`) | Yes | | +| Enum definitions (most) | Yes | Suffix disambiguation requires class-name collision check | +| Enum open-extension wrappers | Yes | Extensible types with `other-*` values | +| Attributes struct pattern | Yes | | +| Child cardinality (optional/required/set) | Yes | | +| Sequence/choice/group structure | Yes | | +| `Properties` class name | No | `attributes` -> `Properties` override | +| `MetronomeRelation` frozen value | No | Only valid value is `"equals"` | +| `Accidental` double-flat remap | No | Error-tolerance hand-patch | +| `Dynamics` child-tag serialization | No | Non-standard serialization pattern | +| `Note` complexity / JIT alloc | No | Manual performance work | +| `PlaybackSound` X-macro pattern | No | Or unify with Enums.h approach | +| SMUFL glyph map | No | Separate data source (`glyphnames.json`) | +| `DocumentSpec` old-style enum | No | Minor inconsistency; could normalize | +| `PositiveDivisionsValue` TODO | No | Needs resolution | +| Required-attribute error strings | Partially | Bug in original; a new generator should fix | +| Shared attribute group structs | Yes (attribute groups) | Explicit mapping step needed | diff --git a/gen/experiment/gen_attrs.py b/gen/experiment/gen_attrs.py new file mode 100644 index 000000000..b0b3c0451 --- /dev/null +++ b/gen/experiment/gen_attrs.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python3 +"""Iteration 3: derive *Attributes struct field lists by flattening each complexType's own +attributes + transitive attributeGroup refs, in document order, and diff field names/order +against the real *Attributes.h headers.""" +import os +import re +import xml.etree.ElementTree as ET + +XS = "{http://www.w3.org/2001/XMLSchema}" +ELDIR = "src/private/mx/core/elements" + + +def pascal(n): + return "".join(p[:1].upper() + p[1:] for p in re.split(r"[-_]", n)) + + +def camel(n): + p = re.split(r"[-_]", n) + return p[0].lower() + "".join(x[:1].upper() + x[1:] for x in p[1:]) + + +def main(): + root = ET.parse("docs/musicxml.xsd").getroot() + + attr_groups = {} # name -> element (xs:attributeGroup definition) + for ag in root.iter(f"{XS}attributeGroup"): + if ag.get("name"): + attr_groups[ag.get("name")] = ag + + def collect(node, seen): + """Ordered list of attribute names from node's own xs:attribute + nested + xs:attributeGroup refs (transitive, document order).""" + out = [] + for child in node: + tag = child.tag + if tag == f"{XS}attribute" and child.get("name"): + out.append(child.get("name")) + elif tag == f"{XS}attributeGroup" and child.get("ref"): + ref = child.get("ref") + if ref in seen: + continue + seen.add(ref) + if ref in attr_groups: + out += collect(attr_groups[ref], seen) + elif tag in (f"{XS}simpleContent", f"{XS}complexContent", + f"{XS}extension", f"{XS}restriction"): + out += collect(child, seen) + return out + + # complexType name -> ordered attribute names + derived = {} + for ct in root.iter(f"{XS}complexType"): + if not ct.get("name"): + continue + attrs = collect(ct, set()) + if attrs: + derived[pascal(ct.get("name")) + "Attributes"] = [camel(a) for a in attrs] + + def real_fields(path): + fields, instruct = [], False + for line in open(path): + s = line.strip() + if s.startswith("struct ") and "Attributes" in s: + instruct = True + continue + if instruct: + if s.startswith("private:") or s == "};": + break + m = re.match(r"[\w:]+(?:<[^>]+>)?\s+(\w+);$", s) + if m and not m.group(1).startswith("has"): + fields.append(m.group(1)) + return fields + + total = exact = name_only = mismatch = 0 + missing = [] + mism_ex = [] + for h in sorted(os.listdir(ELDIR)): + if not h.endswith("Attributes.h"): + continue + cls = h[:-2] + if cls not in derived: + missing.append(cls) + continue + total += 1 + rf = real_fields(os.path.join(ELDIR, h)) + df = derived[cls] + if df == rf: + exact += 1 + elif sorted(df) == sorted(rf): + name_only += 1 # same set, different order + mism_ex.append(f"{cls} ORDER d={df[:5]} r={rf[:5]}") + else: + mismatch += 1 + mism_ex.append(f"{cls} SET d-only={sorted(set(df)-set(rf))[:4]} " + f"r-only={sorted(set(rf)-set(df))[:4]}") + + print(f"*Attributes headers in elements/ : " + f"{len([h for h in os.listdir(ELDIR) if h.endswith('Attributes.h')])}") + print(f"matched a derived complexType : {total}") + print(f" exact (fields + order) : {exact}") + print(f" same fields, different order : {name_only}") + print(f" field-set mismatch : {mismatch}") + print(f"no derived complexType (name unknown) : {len(missing)}") + print() + print("--- headers with no matching complexType (struct-name rule gap) ---") + print(" " + ", ".join(missing[:30])) + print() + print("--- field mismatches (first 20) ---") + for e in mism_ex[:20]: + print(" " + e) + + +main() diff --git a/gen/experiment/gen_enum_members.py b/gen/experiment/gen_enum_members.py new file mode 100644 index 000000000..1f8aba6b9 --- /dev/null +++ b/gen/experiment/gen_enum_members.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python3 +"""Iteration 2: derive enum MEMBER identifiers for every enumeration simpleType and diff +against the real Enums.h bodies. Surfaces the member-naming rule, the reserved-word rule, +and any value that is not algorithmically derivable (digit-leading values, etc.).""" +import re +import xml.etree.ElementTree as ET + +XS = "{http://www.w3.org/2001/XMLSchema}" + +CPP_KEYWORDS = { + "continue", "double", "long", "short", "int", "float", "bool", "char", "class", + "struct", "enum", "union", "void", "for", "while", "do", "if", "else", "switch", + "case", "default", "break", "return", "new", "delete", "this", "true", "false", + "const", "static", "virtual", "public", "private", "protected", "namespace", + "using", "template", "typename", "operator", "and", "or", "not", "xor", "auto", + "register", "signed", "unsigned", "goto", "throw", "try", "catch", +} + + +def camel(value: str) -> str: + parts = re.split(r"[-_ ]", value) + out = parts[0].lower() + "".join(p[:1].upper() + p[1:] for p in parts[1:]) + return out + "_" if out in CPP_KEYWORDS else out + + +def derivable(value: str) -> bool: + # A value is rule-derivable iff it does not begin with a digit (digit-leading values + # were hand-spelled to English in mx/core: 1024th -> oneThousandTwentyFourth). + return not value[:1].isdigit() + + +def real_bodies(path): + bodies, cur = {}, None + for line in open(path): + m = re.match(r"\s*enum class (\w+)", line) + if m: + cur, bodies[cur] = m.group(1), [] + continue + if cur is not None: + if line.strip() == "};": + cur = None + continue + mv = re.match(r"\s*(\w+)\s*=\s*\d+", line) + if mv: + bodies[cur].append(mv.group(1)) + return bodies + + +def main(): + root = ET.parse("docs/musicxml.xsd").getroot() + class_names = set() + for tag in ("element", "complexType"): + for e in root.iter(f"{XS}{tag}"): + if e.get("name"): + class_names.add("".join(p[:1].upper() + p[1:] + for p in re.split(r"[-_]", e.get("name")))) + real = real_bodies("src/private/mx/core/Enums.h") + + total = match = nonderiv_types = 0 + nonderiv_examples = [] + mismatch_examples = [] + for st in root.iter(f"{XS}simpleType"): + name = st.get("name") + if not name: + continue + restr = st.find(f"{XS}restriction") + if restr is None: + continue + vals = [e.get("value") for e in restr.findall(f"{XS}enumeration")] + if not vals: + continue + base = "".join(p[:1].upper() + p[1:] for p in re.split(r"[-_]", name)) + cpp = base + "Enum" if base in class_names else base + if cpp not in real: + continue + total += 1 + derived_members = [camel(v) for v in vals] + if not all(derivable(v) for v in vals): + nonderiv_types += 1 + bad = [v for v in vals if not derivable(v)] + nonderiv_examples.append(f"{name}: {bad[:6]}") + continue + if derived_members == real[cpp]: + match += 1 + else: + d = [(a, b) for a, b in zip(derived_members, real[cpp]) if a != b] + mismatch_examples.append(f"{cpp}: {d[:4]} (len d{len(derived_members)} r{len(real[cpp])})") + + print(f"enums compared (name-matched) : {total}") + print(f"fully RULE-derivable members, exact : {match}") + print(f"types with digit-leading values (EXC): {nonderiv_types}") + print(f"other member mismatches : {len(mismatch_examples)}") + print() + print("--- digit-leading (hand-spelled English, not derivable) ---") + for e in nonderiv_examples: + print(f" {e}") + print() + print("--- other mismatches (rule gaps) ---") + for e in mismatch_examples[:25]: + print(f" {e}") + + +main() diff --git a/gen/experiment/gen_enums.py b/gen/experiment/gen_enums.py new file mode 100644 index 000000000..ba884da08 --- /dev/null +++ b/gen/experiment/gen_enums.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python3 +"""Experimental codegen probe: derive mx/core Enums.h enum-class names from the XSD. + +Goal is NOT a finished generator. It applies the hypothesized derivation rules to every +enumeration simpleType, then diffs the derived set against the real Enums.h. Every mismatch +is a discovered exception for docs/ai/project/gen-overrides.md. +""" +import re +import sys +import xml.etree.ElementTree as ET + +XS = "{http://www.w3.org/2001/XMLSchema}" +XSD = "docs/musicxml.xsd" +ENUMS_H = "src/private/mx/core/Enums.h" + + +def pascal(name: str) -> str: + return "".join(p[:1].upper() + p[1:] for p in re.split(r"[-_]", name)) + + +def main() -> None: + tree = ET.parse(XSD) + root = tree.getroot() + + # Set of class names that an enum name could collide with: every element name and + # every complexType name, PascalCased. (Hypothesis: collision -> 'Enum' suffix.) + class_names = set() + for el in root.iter(f"{XS}element"): + if el.get("name"): + class_names.add(pascal(el.get("name"))) + for ct in root.iter(f"{XS}complexType"): + if ct.get("name"): + class_names.add(pascal(ct.get("name"))) + + # Every simpleType whose restriction carries xs:enumeration values is an enum candidate. + enum_types = {} # xsd type name -> [values] + union_members = set() # simpleTypes referenced inside an xs:union (open-extension hint) + for st in root.iter(f"{XS}simpleType"): + name = st.get("name") + union = st.find(f"{XS}union") + if union is not None and union.get("memberTypes"): + for m in union.get("memberTypes").split(): + union_members.add(m) + if not name: + continue + restr = st.find(f"{XS}restriction") + if restr is None: + continue + vals = [e.get("value") for e in restr.findall(f"{XS}enumeration")] + if vals: + enum_types[name] = vals + + derived = {} # derived C++ enum-class name -> xsd type name + for xsd_name in enum_types: + base = pascal(xsd_name) + if base in class_names: + cpp = base + "Enum" # collision rule + else: + cpp = base + derived[cpp] = xsd_name + + # Real enum-class names from Enums.h. + real = set() + for line in open(ENUMS_H): + m = re.match(r"\s*enum class (\w+)", line) + if m: + real.add(m.group(1)) + + dset = set(derived) + only_real = sorted(real - dset) # in mx/core, generator missed -> exceptions + only_derived = sorted(dset - real) # generator invented -> over-generation + + print(f"XSD enumeration simpleTypes : {len(enum_types)}") + print(f"derived enum-class names : {len(dset)}") + print(f"real enum-class names : {len(real)}") + print(f"exact-match : {len(dset & real)}") + print() + print(f"--- in Enums.h but NOT derived ({len(only_real)}) [missed / special] ---") + for n in only_real: + print(f" {n}") + print() + print(f"--- derived but NOT in Enums.h ({len(only_derived)}) [over-generated] ---") + for n in only_derived: + print(f" {n} (xsd: {derived[n]})") + + +if __name__ == "__main__": + sys.exit(main()) From fa4b57d7b4e9d371e59a74e1cc02cb13f46b4156 Mon Sep 17 00:00:00 2001 From: Matthew James Briggs Date: Thu, 21 May 2026 14:39:39 +0200 Subject: [PATCH 3/3] initial docs regarding the gen project, reorganized --- .gitignore | 3 + AGENTS.md | 23 +- docs/ai/project/AGENTS.md | 13 - docs/ai/project/agenda.md | 108 ----- docs/ai/project/build-and-ci-design.md | 315 ------------- docs/ai/projects/AGENTS.md | 4 + .../projects/gen/design/forensics.md} | 0 .../gen/design/overrides.md} | 8 +- .../gen/design/scoring.md} | 62 +-- docs/ai/projects/gen/index.md | 64 +++ docs/ai/projects/gen/iteration-notes.md | 425 ++++++++++++++++++ docs/ai/projects/gen/log.md | 41 ++ docs/ai/projects/gen/plan.md | 64 +++ docs/ai/projects/gen/state.md | 53 +++ 14 files changed, 676 insertions(+), 507 deletions(-) delete mode 100644 docs/ai/project/AGENTS.md delete mode 100644 docs/ai/project/agenda.md delete mode 100644 docs/ai/project/build-and-ci-design.md create mode 100644 docs/ai/projects/AGENTS.md rename docs/{codegen-forensics.md => ai/projects/gen/design/forensics.md} (100%) rename docs/ai/{project/gen-overrides.md => projects/gen/design/overrides.md} (97%) rename docs/ai/{project/change-penalty.md => projects/gen/design/scoring.md} (75%) create mode 100644 docs/ai/projects/gen/index.md create mode 100644 docs/ai/projects/gen/iteration-notes.md create mode 100644 docs/ai/projects/gen/log.md create mode 100644 docs/ai/projects/gen/plan.md create mode 100644 docs/ai/projects/gen/state.md diff --git a/.gitignore b/.gitignore index 0c12c09a8..d57b7c405 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,6 @@ src/private/mxtest/file/PathRoot.h **/xcshareddata/ *.DS_Store compile_commands.json + +# files for my notes and or ai instructions +.prompt diff --git a/AGENTS.md b/AGENTS.md index bcea149fa..fc6e7d7eb 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -56,24 +56,17 @@ specification. Rather, the goal of code generation is bespoke, to produce what i ## Quality Gates -When modifying any file under `src/`, run: +Always run `make fmt` after modifying code under `src/`. -``` -make fmt && make check && make test -``` +To see whether your code changes are sound, follow that with: +- for changes in `src/private/mx/core/*`: `make test-all` (very slow, can be more than 10 minutes) +- for changes not in `src/private/mx/core/*`: `make test` (faster, can take a couple minues) -If the changes include anything under `src/private/mx/core/`, use `make test-all` instead of -`make test`. +Check for warnings with: `make check`. -`make fmt` and `make check` run inside Docker (requires Docker on the host). +CI will run all of these plus the `xcode` targets. -On `make check` failure, run `make fmt` to fix formatting, then address any remaining warnings -manually. - -See `docs/ai/project/build-and-ci-design.md` for full details on the CI pipeline and quality gate -design. - -## The Project +## Current Project We are working on reverse engineering a new codegen system to regenerate mx/core for MusicXML 4.0. -See the project directory @./docs/ai/project/AGENTS.md +See the project directory `./docs/ai/project/gen`. diff --git a/docs/ai/project/AGENTS.md b/docs/ai/project/AGENTS.md deleted file mode 100644 index 4ccaf9605..000000000 --- a/docs/ai/project/AGENTS.md +++ /dev/null @@ -1,13 +0,0 @@ -# Project - -This is the directory for supporting MusicXML 4.0. - -./agenda.md is the TODO list of work items. ./build-and-ci-design.md is the plan for how Makefile -and CI targets will lint, build, test and fmt the code. - -## Note on mx/core/ - -The files in `src/private/mx/core/` were originally machine-generated from the MusicXML XSD. -The codegen program no longer exists. These files are normal hand-edited source now and must pass -all quality gates. A future codegen rewrite will re-own them. Do not treat them as generated or -read-only. diff --git a/docs/ai/project/agenda.md b/docs/ai/project/agenda.md deleted file mode 100644 index 4508ef7de..000000000 --- a/docs/ai/project/agenda.md +++ /dev/null @@ -1,108 +0,0 @@ -# Agenda - -This is the project plan for supporting MusicXML 4.0 - -## Phase 0: Prepare for AI Development (DONE) - -## Phase 1: Reverse Engineer Codegen - -This is a difficult process in which we need to reverse engineer and write a codegen program that, -when we run it using the same/current MusicXML schema, regenerates what we now see in mx/core. - -We are not ready to work on MusicXML 4.0 yet. First we want to be able to reliably reproduce the -code we find in mx/core, such that running codegen on the current schema produces the minimal diff -possible to the generated code. - -First I want to design the rules and evaluation criteria for a "regenerated" mx/core. When the gen -program runs, it should output it's results on top of mx/core. The diff should be as small as -possible from the generated code, however, no cheating. Everything in musicxml.xsd must result in -generated code output. - -When evaluating a small diff, consider the following rubrick. We want to minimize CHANGE_PENALTY. -Change points are assigned, 1 per line (whether addition or deletion), multiplied by the following -factors: -- 1: whitespace anywhere -- 1.5: comment changes in `mx/core` -- 2: non-whitespace code changes in `mx/core/*.cpp` files -- 5: non-whitespace code changes in `mx/core/*.h` files -- 10: changes in `mx/impl` files -- FAIL (infinity): changes in `mx/api` files - -These multiply by a diff analysis and lead to a CHANGE_PENALTY score, less is better. If static -analysis of the codegen program reveals that it is skipping parts of MusicXML XSD, then the program -is disqualified, it failed. - -Another analysis is conducted on the codegen program itself for readability, human -comprehensability, separation of concerns, extensibility and soundness of design. For example, a -program with a bunch of if/else statements to deal with special conditions would fair worse than a -program that has a well designed mechanism for defining codegen overrides or rule exceptions. TODO: -determine what sort of analysis tools are available for this. Call it CODEGEN_PROGRAM_QUALITY. - -Codegen program language: open to discussion and choosing the best tool for the job. - -Now consider that more than one agent attempts to solve this codegen problem in parallel producing -different programs. They choose a language, then figure out how to generate mx/core from -MusicXML.xsd keeping the scoring rubric in mind. They must produce a program that generates code and -that passes the mx quality gates. At the end their program and it's output are scored by an -impartial agent. - -Once we have a couple of attempts at this, we take the best one and if it can still be improved, we -could repeat the process but this time using agents who are asked to improve the winning program. - -What do you think of this plan? Will it work? Would you be able to help me lock down the plan better -with the grill me skill should I choose to move forward? - -### Open Questions Requiring Grill-Me Sessions - -Each item below needs a `/grill-me` session before Phase 1 agent work begins. Each session should -produce a doc in `docs/ai/project/`. - -- [x] **Override mechanism** (`phase1-overrides.md`) - Are hand-coded exceptions to codegen rules - allowed? If so, what form do they take, and how does CODEGEN_PROGRAM_QUALITY penalize them? This - resolves the tension between "no cheating" and the known human choices in mx/core. - OUTPUT=./gen-overrides.md - -- [x] **CHANGE_PENALTY threshold** (`phase1-scoring-thresholds.md`) - What numeric score is "good - enough" to exit Phase 1 and move to Phase 2? Without a pass/fail threshold the phase has no exit - criterion. OUTPUT=./change-penalty.md - - Note from `gen-overrides.md`: the override investigation found `mx/core` has legacy - XSD-infidelity (the "FIX" category), e.g. 45 attribute structs silently omit the `color` - attribute the XSD declares. A faithful generator must emit it, producing a large but correct - diff. This session must give faithfulness precedence over raw diff size, or the threshold - rewards reproducing legacy bugs. See the FIX section and Consequences in `gen-overrides.md`. - -- [ ] **CODEGEN_PROGRAM_QUALITY criteria** (`phase1-quality-criteria.md`) - How is program quality - measured concretely? Static analysis tools, manual rubric, or both? The current plan has a TODO - here. OUTPUT=./codegen-program-quality.md - -- [ ] **Language constraints** (`phase1-language-constraints.md`) - Which languages are permitted - for competing agents? Leaving this fully open produces incomparable results and risks poor tool - choices. OUTPUT=./language-constraints.md - -- [ ] **Systematic-gap scoring** (`phase1-systematic-gaps.md`) - How does scoring handle a program - that is systematically correct for 95% of elements but misses one XSD pattern that appears 300 - times? The current rubric has no partial-credit mechanism. OUTPUT=./scoring-gap.md (idea, perhaps - this can be solved by assigning a very large score for getting something that passes mx quality - gates without skipping anything in MusicXML.xsd) - - Note from `gen-overrides.md`: the missing-`color` FIX (45 structs) is a concrete instance of - the inverse problem - a systematic gap that already exists in `mx/core`, where the *correct* - generator must add ~300 lines and the rubric as written penalizes it. Use this as the worked - example for the partial-credit / faithfulness-over-diff mechanism. - -## Phase 2: Modernize or Improve the C++ - -Before we codegen 4.0, maybe we should improve what is being generated from the current MusicXML -Spec for performance and for new C++ features, e.g. enum variants etc. Can it be more optimal? - -## Phase 3: Analyze which features of MusicXML are inaccessible from mx/api - -## Phase 4: Generate MusicXML 4.0 Types - -## Phase 5: Surface MusicXML 4.0 Features to mxapi types - -## Random Ass TODOs - -Not related to the larger project plan: - -- [ ] Remove CircleCI Stuff -- [ ] Cleanup the Changelog diff --git a/docs/ai/project/build-and-ci-design.md b/docs/ai/project/build-and-ci-design.md deleted file mode 100644 index 08b22dba8..000000000 --- a/docs/ai/project/build-and-ci-design.md +++ /dev/null @@ -1,315 +0,0 @@ -# Build and CI Design - -## Overview - -This document describes the formatting, compiler-warning enforcement, and CI pipeline for mx. It -also defines the quality gates that coding agents must satisfy when modifying `src/`. - -### Note on `mx/core/` - -The files in `src/private/mx/core/` were originally machine-generated from the MusicXML XSD. -The codegen program no longer exists. These files are treated as normal hand-edited source for the -current gates (formatting and compiler warnings) and must pass them like any other code. They are -not linted (see Future Work). A future codegen rewrite will re-own these files and emit code that -passes the gates from the start. - -### Design Principle: One Authoritative Toolchain - -Compiler warning sets and clang-format behavior change between tool versions. CI runners -(`ubuntu-latest`, `macos-latest`, `windows-latest`) float their toolchain versions, so a warning or -formatting CI break can occur with no code change at all. - -To eliminate that fragility, the quality-gate tooling (clang-format and the warning-enforcing -compiler) runs inside a Docker container with pinned tool versions. This gives deterministic, -reproducible results on any machine - local or CI. Platform-specific CI jobs only build and test -with their native toolchains; they enforce no quality gates. - -* * * - -## Toolchain (Docker) - -The quality-gate tools are pinned inside a Docker image built from the `Dockerfile` at the repo -root. The image is Ubuntu 24.04 with **g++-14** and clang-format-18. The gate compiles with GCC (not -clang) so it uses the same compiler family and standard library (libstdc++) as the required Linux CI -jobs - a `make check` pass locally therefore means the GCC jobs compile too. clang-tidy was -previously the reason to use clang + libc++ here; with clang-tidy removed (see Future Work), GCC is -the better choice because it removes the local-vs-CI portability blind spot. Pinning keeps the -`-Wall -Wextra` warning set deterministic. - -### Formatting: clang-format - -Style base: **Microsoft**. This is the closest standard clang-format style to the existing codebase: -4-space indent, Allman braces (opening `{` on its own line for namespaces, classes, and functions). -The one visible change from the historical style is the removal of spaces inside parentheses -(`func( arg )` becomes `func(arg)`). - -A `.clang-format` file at the repo root encodes this style. All C++ files under `src/` are -formatted, including generated files in `mx/core/`. - -### Linting (deferred) - -clang-tidy is **not** a current quality gate. It was evaluated and removed because running it across -the whole tree is not viable. See Future Work for the rationale and the intended scoped -reintroduction. - -### Compiler Warnings - -`CMakeLists.txt` adds `-Wall -Wextra` (GCC/Clang) or `/W4` (MSVC) to the `mx` target. Inside the -Docker container, g++-14 is the compiler. `make check` treats any `warning:` line in the build -output as a failure, and also fails on configure or build errors. - -### CMake Version - -`CMakeLists.txt` requires CMake >= 3.13. The Makefile uses `-S`/`-B` and `--build --parallel`, both -of which require 3.13+. - -* * * - -## Docker - -### Dockerfile - -Located at the repo root. Based on Ubuntu 24.04 with pinned clang-18 packages: - -- `gcc-14`, `g++-14` - compiler and libstdc++ (matches the required Linux CI jobs) -- `clang-format-18` - formatting -- `cmake`, `make` - build tools - -The Dockerfile sets `ENV MX_RUNNING_IN_DOCKER=1`. The Makefile checks this variable to decide -whether to run tools directly or to launch Docker. A `.dockerignore` allowlist keeps the build -context to the source tree and build configuration only. - -### BuildKit Cache - -The Dockerfile uses `RUN --mount=type=cache,target=/workspace/build` for the CMake build directory. -This persists the incremental build cache across Docker invocations on the same machine, avoiding -full recompiles on every `make check` run. - -### Makefile Docker Integration - -The Makefile detects `MX_RUNNING_IN_DOCKER`: - -- **Inside the container** (`MX_RUNNING_IN_DOCKER=1`): runs clang-format and the compiler directly. -- **Outside the container**: runs `docker buildx build` to build the image and execute the requested - target inside it. - -For `make fmt`, which needs to write formatted files back to the host, the Makefile uses -`docker buildx build --output type=local,dest=.` to extract the formatted `src/` tree from a -`scratch` export stage (only `src/` is written back). - -For `make check`, only the exit code matters - the build runs with `--output type=cacheonly`. - -* * * - -## Makefile Targets - -### Developer Workflow - -The standard workflow for any code change under `src/`: - -``` -make fmt && make check && make test -``` - -If the change touches files under `src/private/mx/core/`: - -``` -make fmt && make check && make test-all -``` - -These three commands are all a developer or AI agent needs to verify their work. `fmt` and `check` -run in Docker (deterministic, no local tool installation required). `test` and `test-all` run -natively with the local compiler. - -### Quality Targets (Docker) - -| Target | What it does | -|---------------------|---------------------------------------------------------------| -| `make fmt` | Formats all C++ files under `src/` in-place via Docker | -| `make check` | Quality gate: fmt-check + warning-free build (Docker) | -| `make clean-docker` | Removes the Docker buildx cache | - -`check-docker` is an internal prerequisite that verifies Docker is available on `PATH`. - -### Build Targets (Native) - -| Target | What it does | -|-------------|-------------------------------------------------------| -| `make lib` | Build just the static library (no tests, no examples) | -| `make dev` | Build tests (no slow core tests) + examples | -| `make core` | Build the full suite including slow `mx::core` tests | - -### Run Targets (Native) - -| Target | What it does | -|---------------------|-----------------------------------------------------------| -| `make test` | Build dev, run examples + mxtest. `ARGS=` forwarded | -| `make test-all` | Build core, run examples + full mxtest. `ARGS=` forwarded | -| `make examples-run` | Build dev, then run mxread/mxwrite/mxhide | -| `make all` | Build core, run examples, run full mxtest | - -### Xcode Targets (Native) - -| Target | What it does | -|--------------------|-----------------------------------------------| -| `make xcode-gen` | Runs `cmake -G Xcode -S . -B build/xcode` | -| `make xcode-build` | Builds the generated project via `xcodebuild` | -| `make xcode-test` | Runs tests via `xcodebuild test` | - -### Housekeeping - -| Target | What it does | -|---------------------|---------------------------------| -| `make clean` | Remove the entire `build/` tree | -| `make clean-docker` | Remove the Docker buildx cache | - -### Knobs - -| Variable | Default | Purpose | -|--------------|------------------|------------------------------| -| `JOBS` | auto-detected | Parallel compile jobs | -| `BUILD_TYPE` | `Debug` | CMake build type | -| `GENERATOR` | platform default | CMake generator override | -| `ARGS` | (none) | Forwarded to mxtest (Catch2) | -| `DOCKER` | `docker` | Docker executable | - -* * * - -## CI Design - -### File - -`.github/workflows/ci.yaml` - the primary workflow. - -### Triggers - -```yaml -on: - pull_request: - push: - branches: [master] -``` - -CI runs on every PR update and on every push to `master`. - -### Jobs - -#### linux-gate (required - quality gate + tests) - -Runner: `ubuntu-latest` - -| Step | Command | -|--------------|--------------| -| Quality gate | `make check` | -| Run tests | `make test` | - -The Makefile handles Docker internally - CI just runs `make check`. The Docker image is built from -the repo's `Dockerfile` with BuildKit layer caching via GitHub Actions cache (the Makefile -auto-detects `ACTIONS_RUNTIME_TOKEN` and enables the gha cache only when present). - -This is the authoritative quality gate. Formatting and compiler warnings are enforced here with -pinned tool versions. - -#### linux-core (required - full test suite with GCC) - -Runner: `ubuntu-latest` - -| Step | Command | -|-----------------|-----------------| -| Full test suite | `make test-all` | - -Builds and runs the complete test suite including the slow `mx::core` tests using GCC (the system -compiler). The Docker gate job runs `make test` (no core tests); this job runs `make test-all` and -provides full test-suite coverage. - -#### macos (required - build + tests) - -Runner: `macos-latest` - -| Step | Command | -|-----------|-------------| -| Run tests | `make test` | - -Builds and tests with the system clang. `make test` runs the example programs in addition to -`mxtest`, so the examples are exercised on every platform that runs tests (not just macOS). No -quality gates - those are enforced by linux-gate. - -#### windows (required - build + tests) - -Runner: `windows-latest` - -| Step | Command | -|--------------|----------------------| -| Install make | `choco install make` | -| Run tests | `make test` | - -Builds and tests with MSVC. No quality gates. - -#### xcode (advisory) - -Runner: `macos-latest` - -| Step | Command | -|------------------|--------------------| -| Generate project | `make xcode-gen` | -| Build | `make xcode-build` | -| Test | `make xcode-test` | - -Verifies the Xcode generator path separately from the Unix Makefiles build. - -### Caching - -The linux-gate job caches Docker BuildKit layers via GitHub Actions cache, avoiding a full image -rebuild on every run. The Dockerfile is structured to maximize layer reuse - tool installation -layers change rarely, source code layers change frequently. - -Build-and-test jobs (linux-core, macos, windows) cache their `build/` directory: - -``` -${{ runner.os }}-build-${{ hashFiles('CMakeLists.txt', 'src/**') }} -``` - -### Branch Protection - -The `master` branch requires **linux-gate**, **linux-core**, **macos**, and **windows** to pass -before merge. The **xcode** job is advisory. Merge strategy: regular merge commits (not squash). - -* * * - -## Quality Gates for Coding Agents - -When modifying any file under `src/`, an agent must run: - -``` -make fmt && make check && make test -``` - -If the change touches `src/private/mx/core/`, run `make test-all` instead of `make test`. - -`make check` enforces: - -1. **Formatting** - all files must be formatted per `.clang-format`. `make fmt` fixes formatting. -2. **Compiler warnings** - the build must configure, compile, and emit no `warning:` lines. - -These commands require Docker. If Docker is not available, `make check` will report the error. No -other tool installation is needed for quality gates. - -* * * - -## Future Work: scoped clang-tidy - -clang-tidy is not currently a quality gate. It was evaluated and removed because running it across -the whole tree is not viable: - -- `src/private/mx/core/` holds ~590 generated element `.cpp` files (1182 total including headers). - clang-tidy over all of them measured at roughly 8 s/file (~1.3 hours total). -- With a `src/.*` header filter, clang-tidy re-parses shared headers once per translation - unit and reports millions of duplicated diagnostics. -- The generated `mx/core` code is slated for replacement by a future codegen rewrite, so linting it - now has little value. - -The intended future direction is to reintroduce clang-tidy **scoped to the hand-written public API -and implementation** - starting with `src/include/mx/api/` (`mx/api`) - and explicitly -**excluding generated `mx/core`**. Scoped that way the file count and header-filter scope are small -enough to be a fast, useful gate. This is deferred and is not part of the current pipeline; the -future codegen rewrite is expected to emit `mx/core` that would itself pass such a scoped lint. diff --git a/docs/ai/projects/AGENTS.md b/docs/ai/projects/AGENTS.md new file mode 100644 index 000000000..ea5d21bf4 --- /dev/null +++ b/docs/ai/projects/AGENTS.md @@ -0,0 +1,4 @@ +# Projects + +This is the directory for supporting projects in the `mx` repo. See this repo's `/project` skill to +understand the structure of these subdirectories. diff --git a/docs/codegen-forensics.md b/docs/ai/projects/gen/design/forensics.md similarity index 100% rename from docs/codegen-forensics.md rename to docs/ai/projects/gen/design/forensics.md diff --git a/docs/ai/project/gen-overrides.md b/docs/ai/projects/gen/design/overrides.md similarity index 97% rename from docs/ai/project/gen-overrides.md rename to docs/ai/projects/gen/design/overrides.md index a8b7a6a63..9e48bb051 100644 --- a/docs/ai/project/gen-overrides.md +++ b/docs/ai/projects/gen/design/overrides.md @@ -1,7 +1,7 @@ # Codegen Override Mechanism -Resolves the first Phase 1 open question in `agenda.md`: are hand-coded exceptions to codegen -rules allowed, what form do they take, and how does `CODEGEN_PROGRAM_QUALITY` treat them. The +Are hand-coded exceptions to codegen rules allowed? What form do they take, and how does +`CODEGEN_PROGRAM_QUALITY` treat them? The design below is grounded in a catalog of the actual non-derivable points in `mx/core`, found by deriving code from `docs/musicxml.xsd` and diffing against the checked-in source. @@ -161,7 +161,7 @@ overrides to preserve. - **The mechanism must classify, not just override.** EXC and FIX require opposite treatment. A mechanism that cannot express "this delta is a FIX, score it as correct" forces an agent to either cheat (preserve the bug) or absorb an unfair `CHANGE_PENALTY`. -- **`change-penalty.md` and `scoring-gap.md` must give faithfulness precedence over diff +- **`scoring.md` and the systematic-gap design must give faithfulness precedence over diff size.** The missing-`color` case is concrete proof: ~45 structs of correct `.h` additions (5x multiplier) plus `.cpp` would lose under the rubric as written, which would reward reproducing a legacy bug. This finding belongs in those two grill sessions. @@ -170,7 +170,7 @@ overrides to preserve. ## Method and scope -Derivation probes live in `gen/experiment/` (Python, stdlib `xml.etree`, chosen for +Derivation probes live in `gen/` (Python, stdlib `xml.etree`, chosen for zero-dependency iteration in this investigation; the production generator language is a separate Phase 1 question and is not decided here). Each probe derives one slice from the XSD and diffs against `mx/core`; the measured counts above are reproducible by re-running them. diff --git a/docs/ai/project/change-penalty.md b/docs/ai/projects/gen/design/scoring.md similarity index 75% rename from docs/ai/project/change-penalty.md rename to docs/ai/projects/gen/design/scoring.md index f55acc4bf..9e3ef1d02 100644 --- a/docs/ai/project/change-penalty.md +++ b/docs/ai/projects/gen/design/scoring.md @@ -1,55 +1,13 @@ # CHANGE_PENALTY Threshold and Phase 1 Exit Criterion -```text -Done. Wrote docs/ai/project/change-penalty.md and checked off the agenda item. - - What I studied - - Per /wake-up, I traced AGENTS.md -> docs/ai/project/AGENTS.md -> agenda.md -> gen-overrides.md -> build-and-ci-design.md, plus the WIP commit - f723d00a and gen/experiment/. The first Phase 1 grill question (override mechanism) is done. The next problem is the CHANGE_PENALTY threshold (next - unchecked item, OUTPUT=./change-penalty.md). I verified the central evidence in code, not just in the prior doc: AccidentalAttributes.h has no color - member while ArrowAttributes.h and 25 siblings carry Color color - the FIX inversion is real. - - The recommendation, in brief - - The doc's thesis is contrarian to how the agenda framed the question. "What number is good enough?" is the wrong question: - - 1. The raw-diff rubric is inverted. It ranks the cheating generator (hardcode "skip color in 45 structs", ~0 penalty) strictly above the faithful one - (emit color, ~225+ points at the 5x .h multiplier). Picking a threshold doesn't fix this - it just sets the price of the bug. - 2. Fix: score the unexplained residual, not the raw diff. Every differing line is attributed to a gen-overrides.md category - (RULE/EXC/SUBSTRATE/FIX/ANOMALY). Classified, justified lines score zero; only unclassified lines accrue penalty. FIX stops competing with cheating. - 3. Exit = four gates, not a band. No-skip (disqualifying), quality gates, 100% classification completeness, and residual penalty = 0 modulo a closed, - named allowance list. A tolerance band is itself a cheating surface across 113k lines. - 4. Separated two uses the agenda conflated: residual penalty ranks competitors; the four gates exit the phase. Unit of judgment is the distinct - root-cause defect (one bad ordering rule != thousands of points), with line-penalty as telemetry/tiebreaker. - 5. Flagged mx/impl at 10x as too lenient - any mx/impl diff from a core-only generator signals an interface regression; promoted it to - justify-or-fail. - - I drew the boundary with scoring-gap.md explicitly (it owns recurrence-counting; this doc owns the shared foundation) so the remaining grill docs - don't diverge or duplicate. - - Two open items you may want to weigh in on, since I made the calls unilaterally given no interactive session: - - Residual = 0 instead of a tolerance band. This is the strongest and most opinionated claim. It's defensible for a one-time generator, but it raises - the Phase 1 exit bar significantly versus the agenda's "good enough" framing. - - scoring-gap.md and change-penalty.md overlap heavily (the agenda's own notes put the FIX example in both). I kept them separate per your stated - structure but they could arguably be one doc. - -✻ Sautéed for 3m 48s - -※ recap: Goal: design Phase 1 scoring for the MusicXML codegen rewrite. I wrote docs/ai/project/change-penalty.md recommending - residual-after-classification scoring with four exit gates, and checked off the agenda item. Next: your review of the residual=0 decision. (disable - recaps in /config) -``` - -Resolves the second Phase 1 open question in `agenda.md`: what numeric score is "good enough" to -exit Phase 1. The short answer is that a generous numeric "good enough" is the wrong instrument. The -exit criterion is a conjunction of gates; the numeric penalty's job is to be driven to zero on the -*unexplained residual*, not to define a tolerance budget. This doc depends on the classification -taxonomy established in `gen-overrides.md` (RULE / EXC / SUBSTRATE / FIX / ANOMALY). +What numeric score is "good enough" to exit Phase 1? A generous numeric "good enough" is the wrong +instrument. The exit criterion is a conjunction of gates; the numeric penalty's job is to be driven +to zero on the *unexplained residual*, not to define a tolerance budget. This doc depends on the +classification taxonomy established in `overrides.md` (RULE / EXC / SUBSTRATE / FIX / ANOMALY). ## Context -Two facts shape every decision here, both inherited from `gen-overrides.md`: +Two facts shape every decision here, both inherited from `overrides.md`: - **4.0 codegen is a one-time run.** Phase 1 reproduces the current `mx/core` from the current schema so the generator can be trusted before it is pointed at 4.0. The pass/fail bar exists to @@ -85,7 +43,7 @@ defect. The raw metric punishes one mistake thousands of times. ## The mechanism: penalty is computed over the unexplained residual CHANGE_PENALTY must not be computed over the raw diff. It is computed over the **residual** - the -diff that remains after every differing line is attributed to a category from `gen-overrides.md`. +diff that remains after every differing line is attributed to a category from `overrides.md`. The generator already takes a declarative overrides input; that same manifest is the ledger that attributes diff lines: @@ -97,7 +55,7 @@ attributes diff lines: - **EXC**: lines produced by a justified slot reproducing a deliberate human choice. Scored zero when the slot output matches the checked-in source; any delta is residual. - **SUBSTRATE**: not generation output; out of diff scope by construction (namespace-derived, - analyzer-enforced per `gen-overrides.md`). + analyzer-enforced per `overrides.md`). - **ANOMALY**: each anomaly carries a recorded decision (reproduce or correct). The resulting diff is scored zero *because the decision is recorded and justified*, not because it is small. An anomaly with no recorded decision falls to residual. @@ -217,7 +175,7 @@ The agenda's table is mostly sound for scoring residual. Three adjustments: defect. Inherits this doc's residual-after-classification foundation and defect-as-unit; must not redefine them. - `codegen-program-quality.md`: `CODEGEN_PROGRAM_QUALITY` judges the override mechanism's design - (per `gen-overrides.md`), independent of CHANGE_PENALTY. The two scores are orthogonal; a + (per `overrides.md`), independent of CHANGE_PENALTY. The two scores are orthogonal; a generator can pass Gate D with a poorly designed override mechanism and still fail Phase 1 on quality. Note the cross-dependency, do not merge the metrics. - `language-constraints.md`: unaffected by this doc. @@ -227,7 +185,7 @@ The agenda's table is mostly sound for scoring residual. Three adjustments: - Missing-`color` FIX verified directly: `grep` confirms no `color` member in `src/private/mx/core/elements/AccidentalAttributes.h`; `Color color` present in `ArrowAttributes.h` and 25 siblings. Counts (71 reach `color`, 26 emit, 45 omit) are from - `gen-overrides.md`, reproducible via the probes in `gen/experiment/`. + `overrides.md`, reproducible via the probes in `gen/`. - Tree scale: `src/private/mx/core` is 1182 files and ~113k lines; the 5x `.h` multiplier over 45 FIX additions (~225 points for one FIX) is the concrete inversion that forces residual-after-classification rather than a tuned threshold. @@ -241,5 +199,5 @@ The agenda's table is mostly sound for scoring residual. Three adjustments: makes FIX-scored-zero non-gameable) is a build task, not a design question. - The exact diff tooling that attributes lines to manifest entries is an implementation choice; the requirement is per-line attribution with no unclassified lines, not a specific tool. -- ANOMALY decisions (reproduce vs correct) are recorded per `gen-overrides.md`'s ANOMALY table; this +- ANOMALY decisions (reproduce vs correct) are recorded per `overrides.md`'s ANOMALY table; this doc only requires that the decision exists and is justified for the line to score zero. diff --git a/docs/ai/projects/gen/index.md b/docs/ai/projects/gen/index.md new file mode 100644 index 000000000..84dbcbda7 --- /dev/null +++ b/docs/ai/projects/gen/index.md @@ -0,0 +1,64 @@ +--- +created: 2026-05-18 +--- + +# gen + +## Goal + +Reverse engineer the codegen process that produced `mx/core` from MusicXML XSD. Build a generator +that re-produces the existing C++ code from `docs/musicxml.xsd` with minimal unexplained diff, then +point it at MusicXML 4.0 to generate updated types. + +## Index + +- `plan.md` - milestones from reverse-engineering through MusicXML 4.0 PR +- `state.md` - current session state and next-session instructions +- `log.md` - append-only session log +- `iteration-notes.md` - detailed per-iteration findings from the experiment phase (iters 1-7) +- `design/` - design docs (current-state snapshots, not historical) + - `overrides.md` - override taxonomy (RULE/EXC/FIX/SUBSTRATE/ANOMALY) and catalog + - `scoring.md` - CHANGE_PENALTY mechanism and Phase 1 exit gates + - `forensics.md` - analysis of the original Ruby codegen and mx/core patterns + +## Instructions + +### Generator location and how to run + +The generator and eval tools live at `gen/` (not a subdirectory of the project docs): + +``` +python3 gen/generate.py # regenerates C++ on top of src/private/mx/core/elements/ +python3 gen/eval.py # scores the diff +python3 gen/eval.py --verbose # shows individual penalized lines +``` + +After studying the diff, reset with `git checkout -- src/private/mx/core/`. + +Quality gates: `make fmt && make check && make test-all`. + +### Key files outside the project directory + +- `gen/generate.py` - the generator (~2800 lines Python) +- `gen/eval.py` - diff scoring script +- `gen/eval_config.yaml` - scoring category rules +- `docs/musicxml.xsd` - the input XSD schema +- `src/private/mx/core/elements/` - the target output directory (591 .h/.cpp pairs) +- `docs/ai/projects/build-and-ci-design.md` - repo-wide build/CI/formatting docs + +### Eval config policy + +Do NOT autonomously add or change entries in `gen/eval_config.yaml`. When studying the diff, if you +see a pattern that should be zero or low cost, flag it to the user with the pattern, a sample diff +line, and your reasoning. The user decides whether to add it to the config. + +### Commit discipline + +Each iteration should end with a commit containing generator changes, eval changes, and updated +project docs (state.md, log.md, and any design doc changes). Reset generated code before committing +(`git checkout -- src/private/mx/core/`). + +### Design doc maintenance + +Design docs in `design/` describe current design state only. When the design evolves, update the doc +in place. Record design changes and rationale in `log.md`. diff --git a/docs/ai/projects/gen/iteration-notes.md b/docs/ai/projects/gen/iteration-notes.md new file mode 100644 index 000000000..507c679ad --- /dev/null +++ b/docs/ai/projects/gen/iteration-notes.md @@ -0,0 +1,425 @@ +# Codegen Experiment Notes + +## Iteration 1 (2026-05-18) + +Generator: `gen/experiment/generate.py` +Coverage: 373 of 383 elements (10 choice-type skipped), 137 attributes structs +Diff: 764 files changed, +4119 -8149 + +### Exact matches +- 297/631 .h files exact +- 200/629 .cpp files exact + +### Diff categories found + +**1. Constructor initializer list formatting (RULE)** +The generator puts ctor init lists on one line. The real code wraps them at ~100-110 chars with +continuation indented to align with the first initializer. After `make fmt` this should resolve - need +to verify. + +**2. Method ordering inconsistency in original code (ANOMALY)** +Two patterns exist for virtual method declarations: +- Pattern A (373 files): `hasAttributes, hasContents, streamAttributes, streamName, streamContents` +- Pattern B (67 files): `hasAttributes, streamAttributes, streamName, hasContents, streamContents` +Generator uses Pattern A (majority). The 67 Pattern B files produce diffs. Normalize to Pattern A. + +**3. Forward declares: sequence order vs alphabetical (RULE gap)** +The checked-in code sorts forward declares alphabetically in some files and by sequence order in +others. The generator uses XSD sequence order. Need to investigate which is canonical and pick one. +Distance/Appearance example: real code has alphabetical, generator has sequence order. + +**4. Group wrapper classes missing (RULE gap - major)** +The real code creates wrapper classes for XSD `xs:group` definitions with a `Group` suffix: +- `EditorialVoiceGroup`, `EditorialVoiceDirectionGroup`, `FullNoteGroup`, etc. +The generator doesn't create these wrapper classes. It uses the group name directly without the suffix. +This causes missing forward declares, wrong type names, and missing accessor methods. +~20+ elements reference group wrappers. + +**5. Choice wrapper classes missing (not yet generated)** +10 choice-type elements are skipped entirely: `time`, `measure-style`, `direction-type`, `dynamics`, +`metronome`, `percussion`, `encoding`, `technical`, `articulations`, `arrow`. +These need `*Choice` class generation. + +**6. XsString/XsToken value parsing: setValue vs parse (RULE)** +String-like types (`XsString`, `XsToken`, `XsID`, `XsIDREF`, `XsNMToken`, `XsAnyUri`) use +`myValue.setValue(xelement.getValue())` in `fromXElementImpl`. +Numeric/enum types use `myValue.parse(xelement.getValue())`. +Generator currently uses `parse` for everything. + +**7. setAttributes parameter name (cosmetic)** +Real code uses `void setAttributes(const XPtr &value)`. +Generator uses `void setAttributes(const XPtr &attributes)`. + +**8. Color attribute FIX diffs (expected, correct)** +45 attributes structs gain a `color` field they were missing. This is a known FIX per +gen-overrides.md. The generator correctly emits these. They produce +additions in .h and .cpp. + +**9. Private helper methods in complex elements (EXC)** +Some complex elements have hand-written private helper methods for specialized parsing: +- `Direction`: `importDirectionTypeSet`, `createDirectionType`, `isDirectionType`, + `isMultiDirectionType` +- `Note`: similar specialized parsing helpers +These are EXC per gen-overrides.md - irreducible per-element code. + +**10. ezxml forward declarations (RULE)** +Some real elements forward-declare `ezxml::XElementIterator`. The generator doesn't emit these. +They correlate with the private helper methods (pattern 9). + +**11. Beam maxOccurs discrepancy (investigation needed)** +The XSD says `beam` in `note` has `maxOccurs="8"`, but my parser reads `maxOccurs` as an int. +The real code uses `BeamSet` (unbounded). Need to handle bounded-but-gt-1 as Set. + +**12. `empty` complexType handling** +`empty` is a named complexType in the XSD with no content. Elements using this type (like +`accordion-high`) should have no attributes, no content - just the element shell. + +**13. Attributes struct naming: type name vs element name** +The generator names attributes structs after the complexType (`FormattedTextAttributes`, +`BarStyleColorAttributes`). The real code names them after the element that uses them. When multiple +elements share a complexType, the real code uses one shared struct but it's named after the type. When +an element has an anonymous type, the struct is named after the element. The generator creates spurious +files for type-named structs that don't exist in the real code. Need to align naming. + +Major spurious files: `FormattedTextAttributes`, `BarStyleColorAttributes`, +`EmptyPrintStyleAlignAttributes`, `EmptyPrintObjectStyleAlignAttributes`, `HammerOnPullOffAttributes`, +`HeelToeAttributes`, `HorizontalTurnAttributes`, `NameDisplayAttributes`, `NoteTypeAttributes`, +`PlacementTextAttributes`, `StyleTextAttributes`, `TextElementDataAttributes`, +`TextFontColorAttributes`, `TypedTextAttributes`. + +**14. Dynamics child elements generated as separate files (should not exist)** +The `dynamics` XSD type is a choice of empty elements (`f`, `ff`, `fff`, etc.). The real code +handles these as inner members of the `Dynamics` class, not as separate element files. Generator +created 24 files (F.h/cpp, Ff.h/cpp, etc.) that should not exist. + +### Priority fixes for next iteration +1. ~~Fix `setValue` vs `parse` for string types~~ DONE +2. Add group wrapper class generation +3. ~~Fix `setAttributes` parameter name~~ DONE (.h=`attributes`, .cpp=`value` matches real code) +4. ~~Handle bounded maxOccurs > 1 as Set~~ DONE +5. Fix forward declare ordering (alphabetical) +6. ~~Don't generate separate files for dynamics child marks~~ DONE +7. ~~Fix attributes struct naming~~ DONE (element-named, except empty-* shared types) +8. Start generating choice classes + +## Iteration 2 (2026-05-18) + +Fixes applied: setValue/parse, setAttributes param, maxOccurs>1 as Set, dynamics suppression, +attrs naming (element-named except shared empty-* types), skip `attributes` element (EXC: Properties). + +Diff: 728 files changed, +4069 -8410 +- .h: 233/592 exact (up from 175 mid-iteration, down from 297 iter-1 due to attrs changes) +- .cpp: 222/590 exact + +### New findings + +**15. Include ordering** +Real code orders includes: `ElementInterface.h`, type headers (`Enums.h`, `Integers.h`, etc.), +`ForwardDeclare.h`, then attrs header. Generator sorts alphabetically, producing different order. + +**16. Private member ordering (value before attrs)** +For text-with-attrs elements, the real code declares `myValue` before `myAttributes` in private +members. Generator puts `myAttributes` first. + +**17. Empty second `private:` block** +Generator adds a second `private:` section with no members for empty elements. Real code doesn't +have this. + +**18. Attributes struct naming: element-named is the rule** +Discovered that 33 element-named attrs structs in the real code are UNREFERENCED dead code. Elements +always use the type-named struct when sharing a type. But most types with >1 user use `empty-*` +naming. Non-empty shared types (like `formatted-text`) generate BOTH a type-named and an +element-named attrs file in the original code, but only the type-named one is referenced. + +Actually, deeper investigation showed the original code uses element-named attrs for all non-empty-* +types. `DisplayText.h` uses `DisplayTextAttributes.h` (element-named), not +`FormattedTextAttributes.h`. The type-named files that exist (`FormattedTextAttributes.h` etc.) are +dead code never committed to the repo. + +**19. CORE_ROOT_ATTRS location anomaly** +`EmptyPrintObjectStyleAlignAttributes` lives in `mx/core/` not `mx/core/elements/`. This is the +anomaly noted in gen-overrides.md. `EmptyPrintStyleAlignAttributes` was never committed anywhere. + +**20. setAttributes .h vs .cpp parameter name mismatch (intentional)** +Real code: .h uses `&attributes`, .cpp uses `&value`. This is an original inconsistency the +generator should reproduce. + +### Priority fixes for iteration 3 +1. ~~Fix include ordering~~ DONE (alphabetical sort matches clang-format) +2. ~~Fix private member ordering (value before attrs)~~ DONE +3. ~~Remove empty second private block for empty elements~~ DONE +4. ~~Fix text-with-attrs ctor to init myAttributes~~ DONE +5. Add group wrapper class generation +6. Fix forward declare ordering +7. Start generating choice classes + +## Iteration 3 (2026-05-18) + +Fixes: include alphabetical sort, private member ordering (value before attrs), removed empty second +private block, text-with-attrs ctor now initializes attrs, core-root-attrs location handling. + +Diff: +3619 -8063 (567 changed files, down from 728 in iter 2) +- .h: 386/592 exact (65%) +- .cpp: 229/590 exact (39%) + +### Findings + +**21. MX_UNUSED(xelement) inconsistency** +Original code always includes `MX_UNUSED(xelement)` for simple-value elements, even for string types +where xelement IS used (via `xelement.getValue()`). This is technically wrong but consistent. +Generator matches this pattern. + +### Remaining diff sources (estimated impact) +- Forward declares in wrong order (~100+ h diffs): children in XSD sequence order vs alphabetical +- Missing group/choice wrapper classes (~50+ diffs): no Group/Choice generation yet +- Method order Pattern B in 67 files: `hasAttributes, streamAttributes, streamName, hasContents` +- Attrs struct content diffs (~45 FIX + structural): color field, extra attrs +- Complex element cpp: missing child includes, wrong ctor init order, etc. +- 33 unreferenced dead-code attrs files: generator doesn't create them + +### Priority fixes for iteration 4 +1. ~~Sort forward declares alphabetically~~ DONE +2. Fix method ordering for Pattern B files (67 files) +3. Generate Group wrapper classes +4. Generate Choice classes + +## Iteration 4 (2026-05-18) + +Fixes: sorted forward declares alphabetically. + +Diff: +3556 -8000 (567 changed files, same as iter 3) +- .h: 386/592 exact (65%, same as iter 3 - forward declares didn't change .h exact count much) +- .cpp: 229/590 exact (39%, same as iter 3) + +Note: The forward declare sort fix was small (3 lines changed in generate.py). It likely improved +some files but the exact-match counts stayed roughly the same because the remaining diffs have +multiple overlapping causes per file. + +### Diff analysis by .h file change size +- 43 files with 1-2 changed lines (likely single-cause fixes) +- 67 files with 3-4 changed lines +- 29 files with 5-8 changed lines +- 67 files with >8 changed lines (multi-cause or structural) + +### Priority fixes for iteration 5 +1. Fix method ordering for Pattern B files (67 files with hasAttributes, streamAttributes, + streamName, hasContents, streamContents order instead of Pattern A) +2. Generate Group wrapper classes (EditorialVoiceGroup, FullNoteGroup, etc.) +3. Generate Choice classes (ArticulationsChoice, NoteChoice, etc.) +4. Fix complex element .cpp child includes and ctor init order + +## Iteration 5 (2026-05-18) + +Fixes applied: +- Pattern B method ordering: elements with complexContent, xs:sequence, xs:choice, or xs:group + references use `hasAttributes, streamAttributes, streamName, hasContents, streamContents` order. + Detection heuristic covers 99.5% of cases. `PATTERN_B_EXCEPTIONS = {"String"}` for the one + text-with-attrs element that uses Pattern B. Affected ~144 files. +- Group wrapper class generation (.h and .cpp) for 11 XSD groups: beat-unit, + display-step-octave, editorial, editorial-voice, editorial-voice-direction, full-note, + harmony-chord, layout, music-data, score-header, time-signature. +- Group children in parent elements: `->streamContents()` call, `->hasContents()` check, Group + suffix naming for groups in GENERATE_GROUPS. +- ElementInterface() ctor fix: only included when element has no value AND no children. +- MX_RETURN_IS_SUCCESS for text-with-attrs fromXElementImpl (was `return isSuccess`). Matches + 113 of 133 real files; 20 outliers use `return isSuccess` (no systematic pattern found). + +Diff: +3083 -7846 (540 changed files, down from 567 in iter 4) +- .h: 402/592 exact (67.9%, up from 65.2%) +- .cpp: 240/590 exact (40.6%, up from 38.8%) + +### Findings + +**22. Pattern B detection heuristic** +Elements with complexContent, xs:sequence, xs:choice, or xs:group in their complexType use Pattern B +method ordering. Only two exceptions found: `String` (Pattern B despite text-with-attrs) and +`Directive` (Pattern A despite having complexContent, but Directive is an EXC/skipped element). + +**23. Group streamContents patterns are per-group hand-coded** +Each of the 11 generated group classes has a unique streamContents implementation: +- 2-child all-optional (EditorialGroup): no firstItem variable, manual inline checks +- 3-child all-optional (EditorialVoiceGroup): firstItem pattern, first child skips check +- Required-only (DisplayStepOctaveGroup, TimeSignatureGroup): direct stream with endl +- Mixed required/optional/set (BeatUnitGroup, LayoutGroup, ScoreHeaderGroup): each unique +- Choice-based (HarmonyChordGroup, FullNoteGroup): switch/special handling +The generator uses a generic template that doesn't match any group exactly. All 11 group .cpp files +have diffs. Group .h files: 6 of 11 match exactly. + +**24. MX_RETURN_IS_SUCCESS vs return isSuccess inconsistency** +For text-with-attrs elements, 113 use `MX_RETURN_IS_SUCCESS` and ~20 use `return isSuccess` in +fromXElementImpl. No systematic pattern distinguishes them (both setValue and parse types appear in +each group). Generator uses the majority pattern (MX_RETURN_IS_SUCCESS). + +**25. MX_UNUSED(xelement) inconsistency in simple-value elements** +Most simple-value elements include `MX_UNUSED(xelement)` even though xelement IS used via +`getValue()`. A few (CreditType, Divisions, SystemDistance, Volume) do NOT include it. Generator +includes it to match the majority. + +**26. Constructor default values** +Some elements have explicit default values in their ctor init list (e.g., `Fifths::myValue{0}`, +`Duration::myValue(1.0)`). The generator uses `myValue()` (default-constructed). These are +type-specific defaults that would require per-type knowledge to reproduce. + +### Priority fixes for iteration 6 +1. ~~Fix complex element .cpp fromXElementImpl - use correct importElement/importGroup signatures~~ DONE +2. ~~Fix complex element .cpp streamContents - correct patterns for required/optional/set/group~~ DONE +3. ~~Fix complex element .cpp hasContents - return true for elements with required children~~ DONE +4. ~~Fix streamAttributes - use return myAttributes->toStream(os) not null check~~ DONE +5. ~~Inline non-GENERATE_GROUPS groups (duration, all-margins, staff, etc.)~~ DONE +6. ~~Handle complexType-level group refs (page-margins etc.)~~ DONE +7. ~~Sort .cpp child includes alphabetically~~ DONE +8. ~~Wrap ctor init lists at ~100 chars~~ DONE +9. Generate Choice classes (deferred to iteration 7) + +## Iteration 6 (2026-05-18) + +Fixes applied: +- **Group inlining**: Groups not in GENERATE_GROUPS (duration, all-margins, left-right-margins, + staff, tuning, voice, footnote, level, non-traditional-key, slash, traditional-key, part-group, + score-part) have their children inlined into parent elements. Propagates minOccurs from group ref + to inlined children (e.g. `` makes staff child optional). +- **Top-level group refs in complexTypes**: Types like `page-margins` that use + `` directly (no xs:sequence wrapper) now correctly parse children. +- **fromXElementImpl**: Changed from wrong `importElement(message, it, endIter, ...)` overloads to + correct signatures: `importElement(message, *it, isSuccess, *myX, myHasX)` with `continue` for + optional children, same with `isXFound` for required, `importGroup(...)` for groups, + `importElementSet(...)` for sets. Added `isDurationFound`-style local bools for required children. +- **streamContents**: Required children stream unconditionally with `->toStream()`. Groups wrapped + in `hasContents()` check with `->streamContents()`. Elements with required non-group children + get `isOneLineOnly = false;` at start + unconditional trailing endl. All-optional elements get + `isOneLineOnly = !hasContents();` at end + conditional endl. +- **hasContents**: Elements with any required non-group child return `true` directly. +- **streamAttributes**: Changed from `if (myAttributes) { ... }` guard to direct + `return myAttributes->toStream(os);` matching real code. +- **.cpp include sort**: Child element includes in .cpp files now sorted alphabetically. +- **Ctor init list wrapping**: Init lists wrap at ~110 chars (matching clang-format behavior). +- Added `make fmt` step to the workflow (run after generate.py, before eval.py). + +Diff: +2813 -6519 (593 changed files, up from 540 in iter 5 due to newly-generated children) +- .h: 403/592 exact (68.1%, slight increase from 67.9%) +- .cpp: 186/590 exact (31.5%, down from 40.6% - more files now generate children but with small + diffs, reducing average penalty per file) +- Eval penalty: 39,297 (down from 44,389 in iter 5, -11.5%) + +### Findings + +**27. XSD groups that are inlined vs wrapped** +The real code treats some XSD groups as direct children (inlined) and others as Group wrapper +classes. Groups in GENERATE_GROUPS get wrapper classes; all others are inlined. Key inlined groups: +`duration` (single element), `staff` (single optional element), `all-margins` (recursive inline to +4 margin elements), `tuning` (3 elements), `voice` (single element). + +**28. Required-child error messages are inconsistent** +Some elements (Clef) have `if (!isSignFound) { message << ... }` error messages after the loop in +fromXElementImpl, but most (Backup, Forward, etc.) do not. The generator currently omits these +messages to match the majority pattern. + +**29. isOneLineOnly placement: END pattern dominates** +Of 14 all-optional elements using `isOneLineOnly = !hasContents()`, 13 place it AFTER child +streaming (END) and use `if (!isOneLineOnly)`. Only AccordionRegistration places it BEFORE +children (START) and uses `if (hasContents())` at the end. + +**30. All-optional streamContents wrapping** +Some elements (Defaults, Properties) wrap the entire streamContents body in +`if (hasContents()) { ... } else { isOneLineOnly = true; }`. The generator uses the simpler +flat pattern. This accounts for some STRUCTURAL diffs in those files. + +**31. Direction.cpp custom helpers may be replaceable** +Direction.cpp has 680 lines with hand-written private helpers (`importDirectionTypeSet`, +`createDirectionType`, etc.). The generated version is 240 lines using standard patterns. These +may be functionally equivalent - testing needed. Same question applies to Credit.cpp. + +**32. Choice handling is the dominant remaining penalty source** +The top 10 penalty files are all related to xs:choice handling: Direction (choice within +sequence), Note (complex choice), Notations, Key, Harmony, Harmonic, Play, etc. The 10 skipped +choice elements plus choice members in complex elements account for ~60% of remaining STRUCTURAL +penalty. Some choice elements have dedicated Choice wrapper classes in real code; others inline the +choice logic directly. + +**33. Bounded maxOccurs (e.g. fermata maxOccurs=2)** +Barline's fermata uses maxOccurs=2 (not unbounded). The real code has bounds checking in +addFermata (`size() < 2`) and removeFermata (`size() > 0`). The generator treats all maxOccurs>1 +as unbounded sets without bounds. + +### Priority fixes for iteration 7 +1. Generate Choice classes - this is the single biggest penalty reduction opportunity (~60% of + remaining STRUCTURAL). Study the real code patterns for ArticulationsChoice, NoteChoice, + LyricTextChoice, KeyChoice etc. +2. Test whether generated Direction.cpp/Credit.cpp pass `make test` - if so, the custom helpers + are unnecessary and can be removed from the EXC list +3. Handle bounded maxOccurs (maxOccurs=2 for fermata, maxOccurs=8 for beam) +4. Fix all-optional streamContents wrapping (if hasContents() { ... } else { isOneLineOnly = true }) +5. Add blank line before MX_RETURN_IS_SUCCESS in fromXElementImpl loop + +## Iteration 7 + +### Fixes applied +- **Enum value parse fix**: Added `is_enum_value_type()` three-way check in `fromXElementImpl` for + simple-value elements. Enums now use `myValue = parseXxx(xelement.getValue())` instead of + `myValue.parse(...)`. Covers both `*Enum` suffix types and types in `needs_parse_func`. +- **Added to needs_parse_func**: BeaterValue, BreathMarkValue, HoleClosedValue, HoleClosedLocation, + TimeSeparator, PrincipalVoiceSymbol, ModeValue. +- **xs:integer type fix**: Changed mapping from `IntType` to `Integer`, added `Integer` to the + Integers.h include list. +- **Bespoke type mappings**: Added `distance-type` -> DistanceType, `line-width-type` -> + LineWidthType, `mode` -> ModeValue. +- **Group unbounded maxOccurs**: Fixed streamContents, hasContents, and fromXElementImpl to handle + group children with maxOccurs > 1 using Set iteration pattern (only harmony-chord had this). +- **Optional group importGroup**: Added `myHas` flag parameter for groups with minOccurs=0 + (e.g., DisplayStepOctaveGroup in Rest). +- **SKIP_ELEMENTS expanded**: Added part-list, harmony, credit, key, lyric, notations, note, + ornaments, part-abbreviation-display, part-name-display, score-instrument, score-part, + time-modification, instrument-sound. All have Choice classes or special patterns the generator + cannot yet produce. +- **GENERATE_GROUPS reduced**: Removed time-signature (has Interchangeable not in XSD group), + harmony-chord (has Choice logic), music-data (has MusicDataChoice), full-note (has + FullNoteTypeChoice). +- **mx/impl fixes** (minimal, with TODO: fixme comments): ArpeggiateFunctions.cpp, + NotationsWriter.cpp, OrnamentsFunctions.cpp - UpDownNone -> UpDown, hasLong -> hasLong_. + +### Eval score +- Total penalty: 29,998 (down from 39,297, -24%) +- .h: 427/592 exact (72.1%, up from 68.1%) +- .cpp: 202/590 exact (34.2%, up from 31.5%) +- Category breakdown: GOOD 535, EXPECTED 378, COSMETIC 386 (193 penalty), STRUCTURAL 5961 + (29,805 penalty), WRONG 0 +- `make check` passes (library compiles clean) +- `make test-all` fails due to test files referencing original API shapes + +### New findings + +**Finding 25**: Attribute group expansion is the single biggest remaining systemic issue. Many +attribute structs (MordentAttributes, AccidentalTextAttributes, HeelAttributes, ToeAttributes, +StrongAccentAttributes, etc.) are missing attributes inherited through `attributeGroup ref` and +`complexContent extension` chains. The XSD parser currently only collects direct `xs:attribute` +declarations, not those from referenced attribute groups like `print-style`, `trill-sound`, +`print-style-align`, etc. This causes ~500+ penalty points from missing attributes in `.cpp` +files and prevents test compilation. + +**Finding 26**: The `long` C++ keyword escaping produces `hasLong_` but the real code uses +`hasLong`. The real code avoids the keyword clash differently (the member is named `long_` but the +has-flag is `hasLong` without underscore). The generator should use `has{PascalName}` where +PascalName is the unescaped attribute name. + +**Finding 27**: Many elements with xs:choice children cannot be generated yet because the real code +wraps them in dedicated `*Choice` wrapper classes (NotationsChoice, NoteChoice, KeyChoice, +CreditChoice, OrnamentsChoice, LyricTextChoice, etc.). These follow the same set-choice/single- +choice patterns identified in iteration 6 but require per-element configuration. Currently 14 +elements and 4 groups are skipped due to missing Choice class generation. + +**Finding 28**: Some XSD simpleType restrictions on xs:string or xs:token are mapped to custom C++ +types in the real code (e.g., `mode` -> ModeValue, `instrument-sound` -> PlaybackSound, +`line-width-type` -> LineWidthType, `distance-type` -> DistanceType). These need explicit bespoke +type mappings since the generator defaults to XsString/XsToken. + +### Priority fixes for iteration 8 +1. **Attribute group expansion** - This is the highest-impact remaining fix. The XSD parser must + follow `attributeGroup ref` references and `complexContent extension base` chains to collect all + inherited attributes. This will fix ~500+ STRUCTURAL penalty points and unblock test compilation. + The groups to handle: print-style, print-style-align, trill-sound, text-formatting, etc. +2. **Expand Choice class generation** - Add more elements to CHOICE_ELEMENT_CONFIG to generate + their Choice wrapper classes. Priority: notations, note, ornaments, key, credit, lyric. +3. **Fix keyword escaping for has-flags** - `hasLong` not `hasLong_` for the bool flag when the + attribute name is a C++ keyword. +4. **Fix all-optional streamContents wrapping** - Still needed from iteration 6. +5. **Continue test compilation fixes** - Once attribute groups are expanded, retry `make test-all` + and fix remaining test compilation errors. diff --git a/docs/ai/projects/gen/log.md b/docs/ai/projects/gen/log.md new file mode 100644 index 000000000..0b03aba73 --- /dev/null +++ b/docs/ai/projects/gen/log.md @@ -0,0 +1,41 @@ +# gen Log + +## 2026-05-18 (pre-project) + +Work began before the /project skill existed. Seven iterations of the codegen experiment were +completed in a single day. The generator (`gen/generate.py`) was built from scratch, starting with +basic element class generation and progressively adding attributes structs, group wrapper classes, +choice classes, enum handling, and fromXElementImpl/streamContents patterns. + +Iteration-by-iteration details and 28 numbered findings are preserved in `iteration-notes.md`. + +Summary of progress across iterations 1-7: +- Iter 1: basic element generation, 297/631 .h exact. Identified 14 diff categories. +- Iter 2: setValue/parse fix, attrs naming. 233/592 .h exact (regression from attrs refactor). +- Iter 3: include ordering, member ordering, empty private block fix. 386/592 .h exact. +- Iter 4: forward declare alphabetical sort. 386/592 .h exact (minimal change). +- Iter 5: Pattern B method ordering, group wrapper generation for 11 groups. 402/592 .h exact. +- Iter 6: group inlining, fromXElementImpl/streamContents patterns, hasContents, streamAttributes. + Eval penalty 39,297. 403/592 .h, 186/590 .cpp exact. +- Iter 7: choice classes for 5 elements, enum parse fix, type mappings, 14 elements skipped. + Eval penalty 29,998. 427/592 .h, 202/590 .cpp exact. + +Three design docs were produced through /grill-me sessions: overrides taxonomy, scoring mechanism, +and codegen forensics (all now in `design/`). + +## 2026-05-19 12:21 + +Project created under `docs/ai/projects/gen/`. Stub files only. Prior work existed in agenda.md, +gen-overrides.md, change-penalty.md, and gen-todo-move-me-later/. + +## 2026-05-19 12:42 + +Migrated all prior work into the /project structure: +- Promoted `gen/experiment/*` to `gen/*` (generator is no longer an "experiment") +- Moved design docs into `docs/ai/projects/gen/design/` (overrides.md, scoring.md, forensics.md) +- Moved experiment notes to `iteration-notes.md` as historical reference +- Updated eval.py path references from `gen/experiment/` to `gen/` +- Wrote index.md with instructions for coding agents +- Wrote state.md with current progress and next-session priorities +- Removed old `gen-todo-move-me-later/` directory +- Updated /project skill to clarify that subdirectories are allowed diff --git a/docs/ai/projects/gen/plan.md b/docs/ai/projects/gen/plan.md new file mode 100644 index 000000000..94e4a06d1 --- /dev/null +++ b/docs/ai/projects/gen/plan.md @@ -0,0 +1,64 @@ +# gen Plan + +## Milestone 1: Reverse-engineer codegen (Phase 1) + +Produce a generator that, given `docs/musicxml.xsd`, regenerates `mx/core` with minimal unexplained +diff. Exit criteria (from `design/scoring.md`): + +- **Gate A** (no-skip): every XSD element, type, attribute, attributeGroup, and group reaches a + code-emitting path. No skipping. +- **Gate B** (quality): `make fmt && make check && make test-all` passes. +- **Gate C** (classification): 100% of diff lines attributed to a category (RULE/EXC/FIX/ANOMALY). +- **Gate D** (residual): unexplained residual penalty = 0. + +Current status: Gate A not met (14 elements skipped). Gate B partially met (make check passes, +make test-all fails). Gates C and D not yet measured against the classification framework. + +### Remaining work for Milestone 1 + +Ordered by expected impact on gates: + +1. Attribute group expansion (unblocks Gate A and Gate B) +2. Choice class generation for remaining skipped elements (Gate A) +3. Keyword escaping fixes (Gate B) +4. streamContents pattern refinements (Gate D) +5. Classification of all remaining diff lines (Gate C) +6. Residual reduction to zero (Gate D) + +### Open design questions (need /grill-me sessions) + +Two grill-me sessions were completed (overrides -> `design/overrides.md`, scoring -> +`design/scoring.md`). Three remain: + +- [ ] **CODEGEN_PROGRAM_QUALITY criteria** - how is program quality measured concretely? Static + analysis tools, manual rubric, or both? +- [ ] **Language constraints** - which languages are permitted for competing agents? (Currently + Python is the de facto choice.) +- [ ] **Systematic-gap scoring** - how does scoring handle a program that is systematically correct + for 95% of elements but misses one XSD pattern that appears 300 times? The missing-color FIX + (45 structs) is a concrete instance of the inverse problem. + +## Milestone 2: Improve codegen / modernize C++ (Phase 2) + +Improve the generated code from the current MusicXML spec: +- more consistent patterns +- modern C++ (e.g. std::variant to reduce object sizes) +- fewer bespoke alterations + +## Milestone 3: Analyze mx/api coverage (Phase 3) + +Determine which MusicXML features are inaccessible from `mx/api`. + +## Milestone 4: Generate MusicXML 4.0 types (Phase 4) + +Replace `docs/musicxml.xsd` with MusicXML 4.0, regenerate. Fix all existing tests. Watch for +backported or bolted-on features like SMuFL that were added with hacks to 3.0/3.1 but are now +first-class in 4.0. Be backward compatible with files that `mx` may have written with those hacks. + +## Milestone 5: Surface 4.0 features to mx/api (Phase 5) + +Expose new MusicXML 4.0 features through the public API. Prioritize those users will want. + +## Milestone 6: PR + +Open a PR introducing MusicXML 4.0 support. diff --git a/docs/ai/projects/gen/state.md b/docs/ai/projects/gen/state.md new file mode 100644 index 000000000..3bd587233 --- /dev/null +++ b/docs/ai/projects/gen/state.md @@ -0,0 +1,53 @@ +# gen State + +## Milestone + +Milestone 1: Reverse-engineer codegen. Working toward Gate B (`make test-all` passing) and reducing +eval penalty toward zero unexplained residual. + +## What was done last session + +Completed iteration 7. Key changes to `gen/generate.py`: +- Choice class generation for 5 elements (direction-type, articulations, bend, technical, percussion) +- Enum parse three-way fix (enum types now use `parseXxx()` not `.parse()`) +- xs:integer mapped to Integer, bespoke type mappings for distance-type, line-width-type, mode +- Group unbounded maxOccurs handling (harmony-chord) +- Optional group importGroup fix (DisplayStepOctaveGroup in Rest) +- Expanded SKIP_ELEMENTS to 14 elements, reduced GENERATE_GROUPS to avoid Choice-dependent groups + +Results: eval penalty 29,998 (down from 39,297, -24%). .h 427/592 exact (72.1%), .cpp 202/590 +(34.2%). `make check` passes. `make test-all` fails. + +## What the next session should do + +Pick the highest-impact fix from the priority list and implement it. Run the generator, eval, study +the diff, update `iteration-notes.md` and this file, commit. + +### Priority fixes (ordered by impact) + +1. **Attribute group expansion** - the single biggest systemic issue. The XSD parser must follow + `attributeGroup ref` and `complexContent extension base` chains to collect all inherited + attributes. Missing attributes cause ~500+ STRUCTURAL penalty and block test compilation. Groups: + print-style, print-style-align, trill-sound, text-formatting, bend-sound, etc. + +2. **Choice class generation for skipped elements** - 14 elements are in SKIP_ELEMENTS to avoid API + shape mismatches with mx/impl. The goal is to generate them properly. Priority: notations, note, + ornaments, key, credit, lyric. Each needs a CHOICE_ELEMENT_CONFIG entry. + +3. **Keyword escaping for has-flags** - use `hasLong` not `hasLong_` when the attribute name is a + C++ keyword. The member is `long_` but the bool flag omits the underscore. + +4. **All-optional streamContents wrapping** - some elements use `if (hasContents()) { ... } else { + isOneLineOnly = true; }` wrapping. The generator uses a simpler flat pattern. + +### Gotchas for the next agent + +- The 14 SKIP_ELEMENTS hide real problems. Removing an element from SKIP_ELEMENTS will likely cause + compilation failures until its Choice class and attribute groups are handled. +- Attribute ordering in structs matters. The existing code uses XSD document order for attributes + within a group, but the order of group expansion (which group's attrs come first) must match the + original code. Study a few real attribute structs before implementing. +- Three mx/impl files have `TODO: fixme` comments from iter 7 (UpDownNone->UpDown, + hasLong->hasLong_ changes): ArpeggiateFunctions.cpp, NotationsWriter.cpp, + OrnamentsFunctions.cpp. These need to be reverted or the generated code needs to match. +- `gen/eval_config.yaml` must not be modified without user approval. Flag patterns, don't fix them.