lvkit 0.3.0__tar.gz → 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {lvkit-0.3.0 → lvkit-0.4.0}/.gitignore +26 -0
- lvkit-0.4.0/NOTICE +26 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/PKG-INFO +20 -2
- {lvkit-0.3.0 → lvkit-0.4.0}/README.md +18 -1
- lvkit-0.4.0/deploy/cloudrun/README.md +84 -0
- lvkit-0.4.0/docs/xml-schema/README.md +102 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/pyproject.toml +10 -1
- lvkit-0.4.0/scripts/audit_terminal_order.py +755 -0
- lvkit-0.4.0/scripts/generate_docs.py +74 -0
- lvkit-0.4.0/scripts/pull_samples.sh +72 -0
- lvkit-0.4.0/scripts/recategorize_vilib.py +283 -0
- lvkit-0.4.0/scripts/render_gallery.py +248 -0
- lvkit-0.4.0/scripts/reproduce_openg_corpus.py +145 -0
- lvkit-0.4.0/scripts/wire_decode_probe.py +233 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/__init__.py +1 -1
- lvkit-0.4.0/src/lvkit/_pylabview_patches.py +271 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/cli.py +173 -48
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/codegen/ast_utils.py +79 -1
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/codegen/builder.py +55 -47
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/codegen/condition_builder.py +6 -1
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/codegen/context.py +24 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/codegen/nodes/__init__.py +34 -11
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/codegen/nodes/case.py +63 -9
- lvkit-0.4.0/src/lvkit/codegen/nodes/compound.py +723 -0
- lvkit-0.4.0/src/lvkit/codegen/nodes/first_call.py +63 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/codegen/nodes/loop.py +208 -31
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/codegen/nodes/primitive.py +81 -8
- lvkit-0.4.0/src/lvkit/codegen/nodes/queue_ops.py +212 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/data/primitives.json +638 -278
- lvkit-0.4.0/src/lvkit/data/vilib/_index.json +32 -0
- lvkit-0.4.0/src/lvkit/data/vilib/addons.json +26 -0
- lvkit-0.4.0/src/lvkit/data/vilib/application-control.json +2128 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/data/vilib/array.json +1018 -804
- lvkit-0.4.0/src/lvkit/data/vilib/boolean.json +492 -0
- lvkit-0.3.0/src/lvkit/data/vilib/cluster.json → lvkit-0.4.0/src/lvkit/data/vilib/cluster-class-variant.json +586 -291
- lvkit-0.4.0/src/lvkit/data/vilib/collection.json +1045 -0
- lvkit-0.4.0/src/lvkit/data/vilib/comparison.json +1642 -0
- lvkit-0.4.0/src/lvkit/data/vilib/connectivity.json +5924 -0
- lvkit-0.4.0/src/lvkit/data/vilib/control-simulation.json +5255 -0
- lvkit-0.4.0/src/lvkit/data/vilib/data-communication.json +9547 -0
- lvkit-0.4.0/src/lvkit/data/vilib/dialog-user-interface.json +2899 -0
- lvkit-0.4.0/src/lvkit/data/vilib/express.json +5086 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/data/vilib/file-io.json +4225 -1670
- lvkit-0.4.0/src/lvkit/data/vilib/graphics-sound.json +8038 -0
- lvkit-0.4.0/src/lvkit/data/vilib/instrument-io.json +3768 -0
- lvkit-0.4.0/src/lvkit/data/vilib/mathematics.json +32367 -0
- lvkit-0.4.0/src/lvkit/data/vilib/measurement-io.json +1046 -0
- lvkit-0.4.0/src/lvkit/data/vilib/numeric.json +3211 -0
- lvkit-0.4.0/src/lvkit/data/vilib/report-generation.json +5661 -0
- lvkit-0.4.0/src/lvkit/data/vilib/signal-processing.json +30948 -0
- lvkit-0.4.0/src/lvkit/data/vilib/string.json +3345 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/data/vilib/structures.json +574 -319
- lvkit-0.4.0/src/lvkit/data/vilib/synchronization.json +2475 -0
- lvkit-0.4.0/src/lvkit/data/vilib/timing.json +857 -0
- lvkit-0.4.0/src/lvkit/data/vilib/waveform.json +8366 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/docs/generate.py +62 -4
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/docs/html_generator.py +323 -253
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/docs/template.css +67 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/extractor.py +61 -11
- lvkit-0.4.0/src/lvkit/graph/builders/__init__.py +26 -0
- lvkit-0.4.0/src/lvkit/graph/builders/context.py +55 -0
- lvkit-0.4.0/src/lvkit/graph/builders/operations.py +152 -0
- lvkit-0.4.0/src/lvkit/graph/builders/refs.py +183 -0
- lvkit-0.4.0/src/lvkit/graph/builders/structures.py +213 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/graph/construction.py +175 -316
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/graph/core.py +11 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/graph/loading.py +48 -16
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/graph/models.py +107 -1
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/graph/operations.py +3 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/graph/queries.py +225 -8
- lvkit-0.4.0/src/lvkit/labview_queue.py +166 -0
- lvkit-0.4.0/src/lvkit/lv_detect.py +248 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/mcp/server.py +45 -5
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/mcp/tools.py +33 -8
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/models.py +43 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/parser/constants.py +12 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/parser/flags.py +10 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/parser/front_panel.py +53 -26
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/parser/models.py +60 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/parser/node_types.py +176 -20
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/parser/nodes/__init__.py +2 -1
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/parser/nodes/base.py +32 -15
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/parser/nodes/case.py +237 -17
- lvkit-0.4.0/src/lvkit/parser/nodes/constant.py +130 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/parser/nodes/decompose.py +1 -3
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/parser/nodes/loop.py +43 -4
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/parser/nodes/sequence.py +1 -3
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/parser/type_mapping.py +8 -3
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/parser/utils.py +49 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/parser/vi.py +110 -32
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/primitive_resolver.py +58 -27
- lvkit-0.4.0/src/lvkit/render/__init__.py +342 -0
- lvkit-0.4.0/src/lvkit/render/backend.py +302 -0
- lvkit-0.4.0/src/lvkit/render/draw.py +1709 -0
- lvkit-0.4.0/src/lvkit/render/glyph.py +1288 -0
- lvkit-0.4.0/src/lvkit/render/icons.py +165 -0
- lvkit-0.4.0/src/lvkit/render/lane_pass.py +525 -0
- lvkit-0.4.0/src/lvkit/render/layout.py +621 -0
- lvkit-0.4.0/src/lvkit/render/nodes.py +901 -0
- lvkit-0.4.0/src/lvkit/render/scene.py +1538 -0
- lvkit-0.4.0/src/lvkit/render/style.py +325 -0
- lvkit-0.4.0/src/lvkit/render/theme_web.py +155 -0
- lvkit-0.4.0/src/lvkit/render/wire_router.py +401 -0
- lvkit-0.4.0/src/lvkit/render/wire_table.py +663 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/skill_templates/lvkit-describe/SKILL.md +2 -2
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/skill_templates/lvkit-resolve-primitive/SKILL.md +61 -70
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/structure.py +53 -14
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/vilib_resolver.py +9 -1
- lvkit-0.4.0/tests/test_array_ops_codegen.py +537 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/test_ast_builder.py +1 -1
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/test_case_codegen.py +101 -0
- lvkit-0.4.0/tests/test_case_parser.py +438 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/test_compound_codegen.py +322 -1
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/test_dependency_path_refs.py +4 -4
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/test_determinism.py +19 -5
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/test_diff.py +43 -29
- lvkit-0.4.0/tests/test_docs_class_hierarchy.py +388 -0
- lvkit-0.4.0/tests/test_docs_render.py +126 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/test_driver_codegen.py +66 -55
- lvkit-0.4.0/tests/test_e2e_codegen.py +508 -0
- lvkit-0.4.0/tests/test_first_call_codegen.py +111 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/test_frame_attribution.py +1 -1
- lvkit-0.4.0/tests/test_glyphs.py +487 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/test_graceful_degradation.py +2 -30
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/test_loop_codegen.py +465 -2
- lvkit-0.4.0/tests/test_lv_detect.py +298 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/test_parallel_codegen.py +13 -41
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/test_parser.py +195 -2
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/test_parser_regression.py +98 -0
- lvkit-0.4.0/tests/test_primitive_resolutions.py +194 -0
- lvkit-0.4.0/tests/test_queue_codegen.py +414 -0
- lvkit-0.4.0/tests/test_render.py +2832 -0
- lvkit-0.4.0/tests/test_unknown_nodes.py +85 -0
- lvkit-0.4.0/tests/test_vilib_docurls.py +158 -0
- lvkit-0.3.0/scripts/generate_docs.py +0 -526
- lvkit-0.3.0/src/lvkit/codegen/nodes/compound.py +0 -181
- lvkit-0.3.0/src/lvkit/data/primitives-from-pdf.json +0 -8452
- lvkit-0.3.0/src/lvkit/data/vilib/_index.json +0 -19
- lvkit-0.3.0/src/lvkit/data/vilib/application-control.json +0 -5408
- lvkit-0.3.0/src/lvkit/data/vilib/boolean.json +0 -704
- lvkit-0.3.0/src/lvkit/data/vilib/comparison.json +0 -2388
- lvkit-0.3.0/src/lvkit/data/vilib/error-handling.json +0 -2274
- lvkit-0.3.0/src/lvkit/data/vilib/numeric.json +0 -1538
- lvkit-0.3.0/src/lvkit/data/vilib/other.json +0 -87782
- lvkit-0.3.0/src/lvkit/data/vilib/string.json +0 -3582
- lvkit-0.3.0/src/lvkit/data/vilib/variant.json +0 -1343
- lvkit-0.3.0/src/lvkit/graph/flowchart.py +0 -281
- lvkit-0.3.0/src/lvkit/parser/nodes/constant.py +0 -55
- lvkit-0.3.0/tests/test_case_parser.py +0 -216
- lvkit-0.3.0/tests/test_e2e_codegen.py +0 -349
- lvkit-0.3.0/tests/test_primitive_resolutions.py +0 -86
- {lvkit-0.3.0 → lvkit-0.4.0}/.pre-commit-config.yaml +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/LICENSE +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/scripts/audit_unresolved.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/scripts/dump_primitive_context.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/scripts/gen_semantics_probe.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/scripts/generate_driver_data.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/scripts/generate_python.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/scripts/populate_vilib.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/scripts/sync_skills.sh +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/_data.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/codegen/README.md +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/codegen/__init__.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/codegen/ast_optimizer.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/codegen/class_builder.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/codegen/dataflow.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/codegen/elementwise.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/codegen/error_handler.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/codegen/expressions.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/codegen/fragment.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/codegen/function.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/codegen/imports.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/codegen/nodes/base.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/codegen/nodes/constant.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/codegen/nodes/formula.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/codegen/nodes/in_place.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/codegen/nodes/invoke_node.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/codegen/nodes/nmux.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/codegen/nodes/printf.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/codegen/nodes/property_node.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/codegen/nodes/sequence.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/codegen/nodes/subvi.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/codegen/stubs.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/codegen/unresolved.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/data/drivers/_index.json +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/data/drivers/daqmx.json +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/data/drivers/nidcpower.json +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/data/drivers/nidigital.json +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/data/drivers/nidmm.json +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/data/drivers/nifgen.json +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/data/drivers/niscope.json +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/data/drivers/niswitch.json +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/data/drivers/serial.json +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/data/drivers/visa.json +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/data/labview_error_codes.json +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/data/openg/_index.json +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/data/openg/array.json +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/data/openg/file.json +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/data/openg/string.json +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/data/openg/time.json +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/data/openg/variant.json +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/data/vilib/_pending_terminals.json +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/data/vilib/_types.json +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/docs/__init__.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/docs/utils.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/formula/__init__.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/formula/cparser.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/formula/emit.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/formula/lexer.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/formula/nodes.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/graph/__init__.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/graph/analysis.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/graph/describe.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/graph/diff.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/labview_error.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/labview_error_codes.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/mcp/__init__.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/mcp/schemas.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/parser/__init__.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/parser/defaults.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/parser/metadata.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/parser/naming.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/parser/type_resolution.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/pipeline.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/project_store.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/py.typed +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/runtime/__init__.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/runtime/lv.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/skill_templates/__init__.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/skill_templates/lvkit-convert/SKILL.md +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/skill_templates/lvkit-idiomatic/SKILL.md +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/skill_templates/lvkit-resolve-vilib/SKILL.md +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/terminal_collector.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/src/lvkit/type_defaults.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/__init__.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/conftest.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/helpers.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/test_ast_optimizer.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/test_codegen_context.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/test_condition_builder.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/test_constant_decoding.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/test_diff_wiring_denoise.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/test_dynamic_dispatch.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/test_elementwise.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/test_error_codegen.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/test_error_handling.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/test_formula_codegen.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/test_formula_runtime.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/test_formula_semantics.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/test_formula_transpile.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/test_in_place_codegen.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/test_lvpy.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/test_naming.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/test_new_codegen.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/test_project_store.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/test_sequence.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/test_soft_codegen.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/test_type_driven_fixes.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/test_type_fields.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/test_type_loading.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/test_type_mapping.py +0 -0
- {lvkit-0.3.0 → lvkit-0.4.0}/tests/test_vi_graph.py +0 -0
|
@@ -79,6 +79,7 @@ dmypy.json
|
|
|
79
79
|
|
|
80
80
|
# Sample LabVIEW projects (external test data)
|
|
81
81
|
samples/
|
|
82
|
+
samples.bak/
|
|
82
83
|
|
|
83
84
|
# Model files
|
|
84
85
|
models/
|
|
@@ -101,3 +102,28 @@ outputs/
|
|
|
101
102
|
docs/*.pdf
|
|
102
103
|
docs/labview_ref_manual.txt
|
|
103
104
|
docs/labview_programming_reference_manual*
|
|
105
|
+
|
|
106
|
+
# NI-derived extracted primitive-icon PNGs (pulled from the reference PDF by
|
|
107
|
+
# scripts/extract_lv_icons.py) — local-only build intermediates. Only the
|
|
108
|
+
# vectorized .svg equivalents (scripts/vectorize_icons.py) are tracked/shipped.
|
|
109
|
+
src/lvkit/data/glyphs/*.png
|
|
110
|
+
|
|
111
|
+
# lv-renderer experiment scratch. Keep only the canonical gallery examples;
|
|
112
|
+
# ignore the throwaway per-iteration review renders and icon-extraction probes.
|
|
113
|
+
experiments/lv-renderer/gallery/*
|
|
114
|
+
!experiments/lv-renderer/gallery/Build.svg
|
|
115
|
+
!experiments/lv-renderer/gallery/Out.svg
|
|
116
|
+
!experiments/lv-renderer/gallery/XML_Loop_Stack_Recursion.svg
|
|
117
|
+
experiments/lv-renderer/icon_extract/
|
|
118
|
+
experiments/lv-renderer/icon_probe/
|
|
119
|
+
experiments/lv-renderer/icon_probe_reverse1d.png
|
|
120
|
+
|
|
121
|
+
# NI-derived vectorized icon SVGs (from the reference PDF) — local-only,
|
|
122
|
+
# regenerated by scripts/vectorize_icons.py; cleanroom package ships none.
|
|
123
|
+
src/lvkit/data/glyphs/*.svg
|
|
124
|
+
|
|
125
|
+
# Local-only experiment/scratch VIs (unprovable provenance — never redistribute)
|
|
126
|
+
experiments/
|
|
127
|
+
|
|
128
|
+
# Claude Code agent worktrees (transient)
|
|
129
|
+
.claude/worktrees/
|
lvkit-0.4.0/NOTICE
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
lvkit
|
|
2
|
+
Copyright 2025-2026 Ryan Friedman
|
|
3
|
+
|
|
4
|
+
This product is an independent, clean-room project. It is not affiliated with,
|
|
5
|
+
authorized by, endorsed by, or sponsored by National Instruments Corporation.
|
|
6
|
+
|
|
7
|
+
LabVIEW, NI, and National Instruments are trademarks of National Instruments
|
|
8
|
+
Corporation, used herein only to identify the file format and software with
|
|
9
|
+
which lvkit interoperates (nominative use).
|
|
10
|
+
|
|
11
|
+
lvkit was developed using only publicly available information: public NI
|
|
12
|
+
documentation, the open-source pylabview project, and observation of VI files.
|
|
13
|
+
It was built without installing or running LabVIEW or any NI software, and
|
|
14
|
+
without the use of any NI source code, internal or non-public specifications,
|
|
15
|
+
or confidential or proprietary materials.
|
|
16
|
+
|
|
17
|
+
lvkit's mappings of LabVIEW primitives and standard-library VIs (in
|
|
18
|
+
src/lvkit/data/) are lvkit's own definitions, derived purely by inference from
|
|
19
|
+
public documentation and from the VI XML produced by pylabview. They are
|
|
20
|
+
best-effort inferences, not authoritative reproductions of any NI
|
|
21
|
+
specification, and they contain no NI documentation text or artwork.
|
|
22
|
+
|
|
23
|
+
lvkit depends on, but does not include, pylabview
|
|
24
|
+
(https://github.com/mefistotelis/pylabview).
|
|
25
|
+
|
|
26
|
+
See PROVENANCE.md for detail.
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lvkit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: Understand and convert LabVIEW VIs to Python without a LabVIEW license
|
|
5
5
|
Project-URL: Repository, https://github.com/pragmatest-dev/lvkit
|
|
6
6
|
Project-URL: Issues, https://github.com/pragmatest-dev/lvkit/issues
|
|
7
7
|
Author: Pragmatest
|
|
8
8
|
License-Expression: Apache-2.0
|
|
9
9
|
License-File: LICENSE
|
|
10
|
+
License-File: NOTICE
|
|
10
11
|
Keywords: ast,code-generation,labview,mcp,ni,static-analysis,vi
|
|
11
12
|
Classifier: Development Status :: 3 - Alpha
|
|
12
13
|
Classifier: Intended Audience :: Developers
|
|
@@ -38,6 +39,8 @@ Read, document, diff, and convert LabVIEW VI files — no LabVIEW license requir
|
|
|
38
39
|
|
|
39
40
|
lvkit parses `.vi`, `.ctl`, `.lvclass`, and `.lvlib` files directly into queryable dependency and dataflow graphs. Use it to document code, track changes in CI, feed VI structure to AI tools, or generate equivalent Python.
|
|
40
41
|
|
|
42
|
+
> **Independent, clean-room project — not affiliated with NI.** lvkit was built using **only publicly available information**: public NI documentation, the open-source [pylabview](https://github.com/mefistotelis/pylabview) project, and observation of VI files. It was developed **without installing or running LabVIEW or any NI software**, and with **no NI source code, internal or non-public specifications, or confidential or proprietary materials**. LabVIEW, NI, and National Instruments are trademarks of National Instruments Corporation, used here only to identify the format lvkit interoperates with; lvkit is not affiliated with, authorized by, endorsed by, or sponsored by NI. See [Cleanroom approach](#cleanroom-approach), [`NOTICE`](NOTICE), and [`PROVENANCE.md`](PROVENANCE.md).
|
|
43
|
+
|
|
41
44
|
## Contents
|
|
42
45
|
|
|
43
46
|
- [Quick Start](#quick-start)
|
|
@@ -167,7 +170,22 @@ Five workflows ship: `lvkit-describe`, `lvkit-convert`, `lvkit-resolve-primitive
|
|
|
167
170
|
|
|
168
171
|
## Cleanroom approach
|
|
169
172
|
|
|
170
|
-
lvkit has no access to LabVIEW source code or runtime. LabVIEW's built-in primitives and standard library VIs are **semantically replaced**: each operation is mapped to an equivalent Python implementation in JSON data files (`src/lvkit/data/primitives.json`, `src/lvkit/data/vilib/`).
|
|
173
|
+
lvkit has no access to LabVIEW source code or runtime. LabVIEW's built-in primitives and standard library VIs are **semantically replaced**: each operation is mapped to an equivalent Python implementation in open, inspectable JSON data files (`src/lvkit/data/primitives.json`, `src/lvkit/data/vilib/`).
|
|
174
|
+
|
|
175
|
+
These mappings are **lvkit's own definitions, derived purely by inference** from two public inputs and nothing else:
|
|
176
|
+
|
|
177
|
+
1. **Public NI documentation** — pages published openly on ni.com, accessed with no login, partner portal, or NDA gate.
|
|
178
|
+
2. **The VI XML produced by [pylabview](https://github.com/mefistotelis/pylabview)** — the open-source parser that extracts the VI binary to XML. That XML is lvkit's *only* window into the format; lvkit has no other view of it.
|
|
179
|
+
|
|
180
|
+
The definitions are open source and fully inspectable, and many carry a note recording how each was inferred (the public doc consulted, the observed terminal signature, a `verified`/`guess_reason` marker). They are **best-effort inferences, not authoritative** — they have been wrong and corrected over time. That imperfection is a direct consequence of working from *only* public documentation and the pylabview XML, with **no access to any internal or authoritative NI specification** — an insider would not need to infer.
|
|
181
|
+
|
|
182
|
+
### Provenance
|
|
183
|
+
|
|
184
|
+
lvkit was developed **using only publicly available information** and clean-room methods. It was built **without installing or running LabVIEW or any NI software**, and with **no NI source code, internal or non-public specifications, or confidential or proprietary materials**. Facts about LabVIEW's behavior are used as facts; no NI documentation prose or artwork is copied or redistributed — primitive glyphs are drawn procedurally, and the shipped data contains no NI text or images. See [`PROVENANCE.md`](PROVENANCE.md).
|
|
185
|
+
|
|
186
|
+
### Trademarks
|
|
187
|
+
|
|
188
|
+
LabVIEW, NI, and National Instruments are trademarks of National Instruments Corporation. lvkit is an independent project and is not affiliated with, authorized by, endorsed by, or sponsored by NI. Those names are used only to identify the file format and software lvkit interoperates with (nominative use).
|
|
171
189
|
|
|
172
190
|
Coverage is incremental. When `lvkit generate` encounters an unmapped primitive or vi.lib VI, it raises an error with diagnostic context so the mapping can be added. `describe`, `docs`, `diff`, and `visualize` are unaffected — they work from the graph, not the semantic mappings.
|
|
173
191
|
|
|
@@ -4,6 +4,8 @@ Read, document, diff, and convert LabVIEW VI files — no LabVIEW license requir
|
|
|
4
4
|
|
|
5
5
|
lvkit parses `.vi`, `.ctl`, `.lvclass`, and `.lvlib` files directly into queryable dependency and dataflow graphs. Use it to document code, track changes in CI, feed VI structure to AI tools, or generate equivalent Python.
|
|
6
6
|
|
|
7
|
+
> **Independent, clean-room project — not affiliated with NI.** lvkit was built using **only publicly available information**: public NI documentation, the open-source [pylabview](https://github.com/mefistotelis/pylabview) project, and observation of VI files. It was developed **without installing or running LabVIEW or any NI software**, and with **no NI source code, internal or non-public specifications, or confidential or proprietary materials**. LabVIEW, NI, and National Instruments are trademarks of National Instruments Corporation, used here only to identify the format lvkit interoperates with; lvkit is not affiliated with, authorized by, endorsed by, or sponsored by NI. See [Cleanroom approach](#cleanroom-approach), [`NOTICE`](NOTICE), and [`PROVENANCE.md`](PROVENANCE.md).
|
|
8
|
+
|
|
7
9
|
## Contents
|
|
8
10
|
|
|
9
11
|
- [Quick Start](#quick-start)
|
|
@@ -133,7 +135,22 @@ Five workflows ship: `lvkit-describe`, `lvkit-convert`, `lvkit-resolve-primitive
|
|
|
133
135
|
|
|
134
136
|
## Cleanroom approach
|
|
135
137
|
|
|
136
|
-
lvkit has no access to LabVIEW source code or runtime. LabVIEW's built-in primitives and standard library VIs are **semantically replaced**: each operation is mapped to an equivalent Python implementation in JSON data files (`src/lvkit/data/primitives.json`, `src/lvkit/data/vilib/`).
|
|
138
|
+
lvkit has no access to LabVIEW source code or runtime. LabVIEW's built-in primitives and standard library VIs are **semantically replaced**: each operation is mapped to an equivalent Python implementation in open, inspectable JSON data files (`src/lvkit/data/primitives.json`, `src/lvkit/data/vilib/`).
|
|
139
|
+
|
|
140
|
+
These mappings are **lvkit's own definitions, derived purely by inference** from two public inputs and nothing else:
|
|
141
|
+
|
|
142
|
+
1. **Public NI documentation** — pages published openly on ni.com, accessed with no login, partner portal, or NDA gate.
|
|
143
|
+
2. **The VI XML produced by [pylabview](https://github.com/mefistotelis/pylabview)** — the open-source parser that extracts the VI binary to XML. That XML is lvkit's *only* window into the format; lvkit has no other view of it.
|
|
144
|
+
|
|
145
|
+
The definitions are open source and fully inspectable, and many carry a note recording how each was inferred (the public doc consulted, the observed terminal signature, a `verified`/`guess_reason` marker). They are **best-effort inferences, not authoritative** — they have been wrong and corrected over time. That imperfection is a direct consequence of working from *only* public documentation and the pylabview XML, with **no access to any internal or authoritative NI specification** — an insider would not need to infer.
|
|
146
|
+
|
|
147
|
+
### Provenance
|
|
148
|
+
|
|
149
|
+
lvkit was developed **using only publicly available information** and clean-room methods. It was built **without installing or running LabVIEW or any NI software**, and with **no NI source code, internal or non-public specifications, or confidential or proprietary materials**. Facts about LabVIEW's behavior are used as facts; no NI documentation prose or artwork is copied or redistributed — primitive glyphs are drawn procedurally, and the shipped data contains no NI text or images. See [`PROVENANCE.md`](PROVENANCE.md).
|
|
150
|
+
|
|
151
|
+
### Trademarks
|
|
152
|
+
|
|
153
|
+
LabVIEW, NI, and National Instruments are trademarks of National Instruments Corporation. lvkit is an independent project and is not affiliated with, authorized by, endorsed by, or sponsored by NI. Those names are used only to identify the file format and software lvkit interoperates with (nominative use).
|
|
137
154
|
|
|
138
155
|
Coverage is incremental. When `lvkit generate` encounters an unmapped primitive or vi.lib VI, it raises an error with diagnostic context so the mapping can be added. `describe`, `docs`, `diff`, and `visualize` are unaffected — they work from the graph, not the semantic mappings.
|
|
139
156
|
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# lvkit on Cloud Run — VI → SVG service
|
|
2
|
+
|
|
3
|
+
A tiny HTTP service: `POST` a `.vi` file, get an SVG block-diagram render back.
|
|
4
|
+
A page can upload a VI and drop the returned SVG straight into the DOM.
|
|
5
|
+
|
|
6
|
+
## Why this works cleanly
|
|
7
|
+
|
|
8
|
+
lvkit needs **no LabVIEW and no native binary**. Extraction shells out to
|
|
9
|
+
`python -m pylabview.readRSRC` (pure Python, an lvkit dependency), and
|
|
10
|
+
`render_vi_file()` returns an SVG string. The container just needs Python +
|
|
11
|
+
lvkit + a writable temp dir — Cloud Run provides `/tmp` (in-memory).
|
|
12
|
+
|
|
13
|
+
Uploads are rendered with `expand_subvis=False`, which is effectively an
|
|
14
|
+
**offline mode**: a standalone VI has no sibling subVI files, so the render
|
|
15
|
+
never reaches the filesystem for dependencies (unresolved subVIs draw as
|
|
16
|
+
fallback boxes). It only reads lvkit's own **bundled** primitive/vilib JSON,
|
|
17
|
+
which ships inside the image. Nothing to configure.
|
|
18
|
+
|
|
19
|
+
## Files
|
|
20
|
+
|
|
21
|
+
| file | purpose |
|
|
22
|
+
|------|---------|
|
|
23
|
+
| `main.py` | Flask app: `GET /` demo page, `GET /health`, `POST /render` |
|
|
24
|
+
| `Dockerfile` | installs lvkit (this branch) + flask/gunicorn; **build context = repo root** |
|
|
25
|
+
| `cloudbuild.yaml` | build → push → deploy in one `gcloud builds submit` |
|
|
26
|
+
| `static/index.html` | drop-a-VI demo page served at `/` |
|
|
27
|
+
| `requirements.txt` | web deps for local dev |
|
|
28
|
+
|
|
29
|
+
## Deploy
|
|
30
|
+
|
|
31
|
+
From the **repo root** (not this folder — the Docker build needs the lvkit
|
|
32
|
+
source in context):
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
gcloud builds submit --config deploy/cloudrun/cloudbuild.yaml \
|
|
36
|
+
--substitutions=_IMAGE=gcr.io/$(gcloud config get-value project)/lvkit-render,_REGION=us-central1 .
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
That builds `deploy/cloudrun/Dockerfile`, pushes the image, and deploys the
|
|
40
|
+
`lvkit-render` service (`--allow-unauthenticated`, 1Gi, 1 CPU, 120s, max 5
|
|
41
|
+
instances — tune in `cloudbuild.yaml`).
|
|
42
|
+
|
|
43
|
+
### Local test
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
pip install -e . # from repo root (installs lvkit + pylabview)
|
|
47
|
+
pip install -r deploy/cloudrun/requirements.txt
|
|
48
|
+
cd deploy/cloudrun && python main.py # http://localhost:8080
|
|
49
|
+
# or exactly like prod:
|
|
50
|
+
docker build -f deploy/cloudrun/Dockerfile -t lvkit-render . # from repo root
|
|
51
|
+
docker run -p 8080:8080 -e PORT=8080 lvkit-render
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Calling it from a page
|
|
55
|
+
|
|
56
|
+
```js
|
|
57
|
+
const fd = new FormData();
|
|
58
|
+
fd.append('vi', fileInput.files[0]);
|
|
59
|
+
const svg = await (await fetch('https://YOUR-URL/render', { method:'POST', body: fd })).text();
|
|
60
|
+
document.getElementById('out').innerHTML = svg; // static picture
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Heads-up: interactive frames
|
|
64
|
+
|
|
65
|
+
The SVG embeds an inline `<script>` for the case/stacked-sequence **frame
|
|
66
|
+
selector**. Browsers do **not** run scripts inserted via `innerHTML`, so a VI
|
|
67
|
+
rendered that way is a static image. To keep the frame toggles working, load the
|
|
68
|
+
SVG so its script executes — e.g. an `<iframe>`:
|
|
69
|
+
|
|
70
|
+
```js
|
|
71
|
+
const url = URL.createObjectURL(new Blob([svg], {type:'image/svg+xml'}));
|
|
72
|
+
iframe.src = url; // scripts inside the SVG run here
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Notes / hardening
|
|
76
|
+
|
|
77
|
+
- **Untrusted input**: you're parsing arbitrary uploaded binaries. Cloud Run's
|
|
78
|
+
per-request container is the isolation boundary; `main.py` caps size at 25 MB
|
|
79
|
+
(Cloud Run's own request limit is 32 MB).
|
|
80
|
+
- **Memory**: `/tmp` is RAM on Cloud Run and holds the upload + extracted XML;
|
|
81
|
+
1Gi is a safe start. Raise `--memory`/lower concurrency for large VIs.
|
|
82
|
+
- **Auth**: `--allow-unauthenticated` is for a public demo. Drop it (and add an
|
|
83
|
+
API key / IAM) for anything real.
|
|
84
|
+
- **Cold start**: first request imports lvkit + pylabview (~1s); fine for a demo.
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# LabVIEW VI XML Schema Reference
|
|
2
|
+
|
|
3
|
+
This directory documents lvkit's current understanding of the XML that
|
|
4
|
+
[pylabview](https://github.com/mefistotelis/pylabview) extracts from a LabVIEW
|
|
5
|
+
`.vi` binary. It is a "genome project" for these archaic, binary-derived fields:
|
|
6
|
+
for each field, *what it is* and *what we currently believe it controls*, with
|
|
7
|
+
the evidence and a confidence level.
|
|
8
|
+
|
|
9
|
+
> **Grounding rule.** Every claim here is traced to lvkit parser code, a
|
|
10
|
+
> pylabview enum/comment, a concrete extracted XML sample, or a confirmed
|
|
11
|
+
> session finding. Where we genuinely do not know a field's meaning, it is
|
|
12
|
+
> marked **confidence = unknown** rather than guessed. (This repo has a hard
|
|
13
|
+
> "never fabricate looked-up facts" rule.)
|
|
14
|
+
|
|
15
|
+
## The three files
|
|
16
|
+
|
|
17
|
+
`extractor.extract_vi_xml(vi_path)` runs one pylabview subprocess per VI and
|
|
18
|
+
writes three sibling XML files next to the `.vi` (plus a pile of `*.bin`
|
|
19
|
+
side-blobs and `*.png` icons):
|
|
20
|
+
|
|
21
|
+
| File | Nickname | Contents | Doc |
|
|
22
|
+
|---|---|---|---|
|
|
23
|
+
| `<name>_BDHb.xml` | **BD** — block-diagram heap | nodes, wires, structures, terminals, constants | [block-diagram.md](block-diagram.md) |
|
|
24
|
+
| `<name>_FPHb.xml` | **FP** — front-panel heap | controls/indicators, connector pane, default data | [front-panel.md](front-panel.md) |
|
|
25
|
+
| `<name>.xml` | **Base / main** | VI settings (LVSR/LVIN), type list (VCTP), dataspace default data (DFDS), link/dependency tables | [dataspace.md](dataspace.md) |
|
|
26
|
+
|
|
27
|
+
Both `_BDHb.xml` and `_FPHb.xml` are **heaps**: recursively nested
|
|
28
|
+
`<SL__arrayElement class="...">` objects, each carrying a `uid`, that model the
|
|
29
|
+
on-screen object tree. The base `.xml` is different in shape — it is a set of
|
|
30
|
+
named binary *sections* (LVSR, VCTP, DFDS, LIvi, LIbd, ...) that pylabview
|
|
31
|
+
renders as structured XML plus `<!-- ... -->` comments.
|
|
32
|
+
|
|
33
|
+
Suffix constants live in `src/lvkit/parser/constants.py:165-167`
|
|
34
|
+
(`BD_XML_SUFFIX`, `FP_XML_SUFFIX`, `MAIN_XML_SUFFIX`), with
|
|
35
|
+
`derive_fp_xml_path` / `derive_main_xml_path` / `derive_vi_name` helpers
|
|
36
|
+
(`constants.py:191-204`).
|
|
37
|
+
|
|
38
|
+
## How the parser reads them
|
|
39
|
+
|
|
40
|
+
Pipeline (`src/lvkit/parser/vi.py:101` `parse_vi`):
|
|
41
|
+
|
|
42
|
+
1. `_parse_metadata(main_xml)` — LVSR/LVIN qualified name, the **type map**
|
|
43
|
+
(`parse_type_map_rich`), and SubVI/dependency link tables. (`vi.py:170`)
|
|
44
|
+
2. `_parse_selector_tables(main_xml)` — case-structure per-frame selector
|
|
45
|
+
values from the DFDS dataspace. (`vi.py:223`)
|
|
46
|
+
3. `_parse_block_diagram(bd_xml, fp_xml, type_map, selector_tables)` — nodes,
|
|
47
|
+
wires, constants, terminals, loops, cases, sequences, IPES. (`vi.py:235`)
|
|
48
|
+
4. `_parse_front_panel(fp_xml, ...)` and `parse_connector_pane(fp_xml)`.
|
|
49
|
+
|
|
50
|
+
## Two SEPARATE type namespaces (they do NOT cross-reference)
|
|
51
|
+
|
|
52
|
+
This is the single most important thing to internalize:
|
|
53
|
+
|
|
54
|
+
- **BD heap `typeDesc` `TypeID(N)`** — an index into the **VCTP** (the
|
|
55
|
+
consolidated type list in the base `.xml`). Terminals, constants, tunnels and
|
|
56
|
+
FP DCOs all carry `<typeDesc>TypeID(N)</typeDesc>`; `N` is a *heap* TypeID,
|
|
57
|
+
resolved through the chain
|
|
58
|
+
`Heap TypeID → Consolidated TypeID → FlatTypeID → VCTP TypeDesc`
|
|
59
|
+
(`parser/type_mapping.py:17` `parse_type_map_rich`,
|
|
60
|
+
`parser/type_resolution.py:53` `resolve_type_rich`).
|
|
61
|
+
- **Dataspace `DataFill TypeID="N"`** — an index into the **DFDS** (dataspace)
|
|
62
|
+
default-data list. Same integer space *shape*, totally different assignment.
|
|
63
|
+
|
|
64
|
+
**A `DataFill TypeID` and a BD `typeDesc TypeID` with the same number are NOT
|
|
65
|
+
the same type.** They are two independent enumerations. The case-selector
|
|
66
|
+
correlation (see [dataspace.md](dataspace.md)) exploits the fact that, *within
|
|
67
|
+
each namespace*, LabVIEW assigns indices in the same DCO-enumeration order — so
|
|
68
|
+
you sort each side by its own index and zip. You never equate the two integers
|
|
69
|
+
directly. (`parser/nodes/case.py:513` `_apply_selector_tables`; session
|
|
70
|
+
finding, confirmed on "Draw Image from File__ogtk.vi".)
|
|
71
|
+
|
|
72
|
+
## Coordinate spaces
|
|
73
|
+
|
|
74
|
+
- All heap rects are LabVIEW `(top, left, bottom, right)` — note the order
|
|
75
|
+
(`render/layout.py:109` `_rect` reorders them to `x1,y1,x2,y2`).
|
|
76
|
+
- A node's `<bounds>` is absolute (relative to the diagram it lives in; the
|
|
77
|
+
renderer accumulates diagram origins while recursing —
|
|
78
|
+
`render/layout.py:383` `walk`).
|
|
79
|
+
- A terminal's `<termBounds>` is **relative to the node's icon origin**, and a
|
|
80
|
+
primitive's icon is *centered* within its clickable `<bounds>` — so the
|
|
81
|
+
renderer computes a centering offset before placing terminals
|
|
82
|
+
(`render/layout.py:252-280` `_map_terms`). Constant part bounds are relative
|
|
83
|
+
to the constant DDO's own top-left (`render/layout.py:118` `_const_value_box`).
|
|
84
|
+
- Selector/label geometry lives in the heap; **selector VALUES do not** — they
|
|
85
|
+
are in the DFDS dataspace (see below).
|
|
86
|
+
|
|
87
|
+
## A note on pylabview `OF__*` enums
|
|
88
|
+
|
|
89
|
+
pylabview's `LVheap.py` defines `OBJ_FIELD_TAGS` with members like
|
|
90
|
+
`OF__objFlags = 172`, `OF__bounds = 14`, `OF__termBounds = 266`
|
|
91
|
+
(`LVheap.py:75-360`). **These integers are attribute-tag IDs** — they identify
|
|
92
|
+
*which serialized attribute* a value belongs to inside the binary heap, and
|
|
93
|
+
they become the XML element *name* (`<objFlags>`, `<bounds>`, ...). They are
|
|
94
|
+
**NOT** bit positions within the `objFlags` integer. Do not conflate the two.
|
|
95
|
+
The bit meanings of `objFlags` are documented per-element in the field docs and
|
|
96
|
+
are lvkit session findings — pylabview does not decode them.
|
|
97
|
+
|
|
98
|
+
## Field docs
|
|
99
|
+
|
|
100
|
+
- [block-diagram.md](block-diagram.md) — `_BDHb.xml`
|
|
101
|
+
- [front-panel.md](front-panel.md) — `_FPHb.xml`
|
|
102
|
+
- [dataspace.md](dataspace.md) — base `.xml` (metadata + VCTP + DFDS + links)
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "lvkit"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.4.0"
|
|
8
8
|
description = "Understand and convert LabVIEW VIs to Python without a LabVIEW license"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -70,6 +70,13 @@ dev = [
|
|
|
70
70
|
# the wheel automatically. The resolvers and `lvkit setup` load
|
|
71
71
|
# them via paths relative to the package or via importlib.resources.
|
|
72
72
|
packages = ["src/lvkit"]
|
|
73
|
+
# lvkit is cleanroom: it ships NO NI-derived primitive artwork. Primitive
|
|
74
|
+
# glyphs are drawn procedurally by the render layer (OriginalGlyphResolver /
|
|
75
|
+
# GeneratedGlyphResolver); un-migrated primitives render as a labeled box. The
|
|
76
|
+
# NI-icon extraction path (a data/glyphs/ asset dir + PdfIconResolver) was
|
|
77
|
+
# removed for licensing. These exclude globs remain as a guard so no such
|
|
78
|
+
# asset can ever be packaged if the directory is reintroduced.
|
|
79
|
+
exclude = ["src/lvkit/data/glyphs/*.png", "src/lvkit/data/glyphs/*.svg"]
|
|
73
80
|
|
|
74
81
|
[tool.hatch.build.targets.sdist]
|
|
75
82
|
include = [
|
|
@@ -86,6 +93,8 @@ exclude = [
|
|
|
86
93
|
"outputs",
|
|
87
94
|
"docs/labview_ref_manual.txt",
|
|
88
95
|
"docs/*.pdf",
|
|
96
|
+
"src/lvkit/data/glyphs/*.png",
|
|
97
|
+
"src/lvkit/data/glyphs/*.svg",
|
|
89
98
|
".lvkit",
|
|
90
99
|
".tmp",
|
|
91
100
|
]
|