{"version":3,"sources":["blackprint.sf.css","src/component/bpnode-header-info.sf","src/component/comp-port-button.sf","src/component/comp-port-input.sf","src/component/comp-port-textarea.sf","src/component/dropdown.sf","src/nodes/internal.sf","src/page.sf"],"names":[],"mappings":"AAEA,kB,CCGA,W,CACC,iB,CACA,e,CACA,kB,CACA,c,CDAD,+B,CCGC,uB,CACC,oB,CACA,oC,CDAF,8B,CCIC,wB,CACC,qB,CACA,U,CACA,wC,CDDF,8B,CCKC,2B,CACC,wB,CACA,sC,CACA,U,CDFF,iC,CCMC,2B,CACC,qC,CACA,U,CDHF,sD,CEOE,kC,CACU,8C,CACA,U,CACA,e,CACA,kB,CACA,S,CACA,U,CACA,c,CFJZ,4D,CEMY,wC,CFHZ,iE,CEWY,U,CFRZ,gE,CEgBY,W,CFbZ,gD,CGiBE,oB,CACC,c,CACA,kC,CACA,U,CACA,qB,CACA,iB,CHdH,iD,CAuBA,oD,CGLE,a,CACC,kB,CHfH,uD,CGiBG,e,CHdH,sD,CICE,c,CACC,e,CACA,a,CACA,4C,CACA,8C,CACG,iB,CACH,e,CACA,qB,CACA,W,CACA,e,CJEH,yE,CIAG,S,CACC,U,CJOJ,6D,CICG,e,CACC,gB,CACA,W,CJEJ,sC,CKjDC,a,CACC,U,CACA,c,CAEA,sC,CACA,gC,CACA,c,CACA,c,CACA,K,CACA,M,CACA,S,CACA,iB,CACA,e,CLmDF,6C,CK9CE,iB,CACC,S,CLiDH,4C,CK9CE,Y,CACC,S,CACA,Q,CACA,4B,CACA,sB,CACA,qD,CLiDH,8D,CK/CG,iB,CL+CH,yD,CK/CG,iB,CLkDH,yC,CK9CE,iB,CACC,e,CACA,gB,CLiDH,yC,CK7CE,iB,CACC,uB,CACA,yB,CACA,wB,CACA,e,CACA,gC,CACA,c,CACA,e,CACA,c,CACA,U,CLgDH,kD,CK7CG,wB,CLqJH,I,CArGA,oD,CA2BA,mE,CKxEI,a,CLgDJ,yD,CK7CI,c,CLgDJ,sD,CK3CG,c,CACC,U,CACA,e,CACA,sB,CACA,kB,CL8CJ,2C,CK1CG,mB,CL6CH,+C,CKzCG,kB,CL4CH,mD,CKxCG,iB,CL2CH,oC,CKrCC,Q,CACC,iB,CACA,S,CL2CF,yD,CKnCC,S,CLsCD,qC,CKjCE,a,CACC,gB,CACA,iB,CACA,e,CACA,c,CACA,yB,CACA,kB,CACA,U,CACA,kB,CACA,0B,CLoCH,iC,CKjCE,Q,CACC,S,CLoCH,sC,CKjCG,Y,CLoCH,0C,CKlCI,gB,CLqCJ,gD,CKhCG,iB,CACC,U,CACA,iB,CLmCJ,6C,CAAA,mD,CK/BG,wB,CACC,e,CLkCJ,4D,CAAA,4D,CAKA,gE,CAAkE,iE,CADlE,4D,CAA8D,4D,CMxM3D,iB,CACC,sC,CACA,oB,CACA,gB,CACA,iB,CACA,c,CNyMJ,yE,CAAA,yE,CAKA,6E,CAA+E,8E,CAD/E,yE,CAA2E,yE,CM1MvE,c,CACC,a,CN2ML,2D,CAAA,2D,CAKA,+D,CAAiE,gE,CADjE,2D,CAA6D,2D,CM1M1D,e,CN2MH,oE,CAAA,oE,CAKA,wE,CAA4E,yE,CAD5E,oE,CAAwE,oE,CM3MrE,Y,CN4MH,gE,CAAA,iE,CMtME,8B,CNyMF,4D,CAAA,gE,CAAA,4D,CMpME,iB,CACC,kB,CNuMH,4D,CAAA,iE,CAAA,4D,CMlME,iB,CACC,kB,CNyMH,oB,CO3JA,iB,CP8JA,iD,CO1JI,uC,CACE,yB,CACA,iB,CACA,0B,CACA,K,CACA,M,CACA,a,CACA,yB,CP6JN,sD,CO1JM,Y,CP6IN,oB,CAgBA,4B,CAAA,2B,COvJE,W,CACE,U,CACA,a,CP0JJ,iC,COtJE,c,CACE,oB,CPyJJ,gC,CAAA,mC,COpJI,0B,CACE,U,CACA,Q,CPuJN,mC,COpJI,mB,CPuJJ,iC,COnJI,kB,CACE,U,CACA,wB,CPsJN,yC,COjJM,e,CACE,kB,CPoJR,6C,CO9IE,e,CPiJF,kE,CO9II,e,CACE,c,CACA,iB,CPiJN,oD,CO7II,iB,CPgJJ,yD,CO7II,e,CPgJJ,kE,CO5II,e,CP+IJ,yE,CO7IM,a,CPgJN,6B,CO1IE,Y,CP6IF,oC,COzIE,U,CP4IF,gD,COtIM,Y,CPyIN,8C,COxIM,c,CP2IN,qD,COvIM,kB,CP0IN,qE,CAIA,2E,COzIM,0B,CACE,4B,CP4IR,wD,COnIM,U,CPsIN,8D,COpIQ,c,CACE,wB,CACA,S,CACA,U,CACA,0B,CPuIV,gD,COjKM,Y,CPoKN,8C,COnKM,c,CPsKN,qD,COlKM,kB,CPqKN,qE,CAIA,2E,COpKM,0B,CACE,4B,CPuKR,wD,CO9JM,U,CPiKN,8D,CO/JQ,c,CACE,wB,CACA,S,CACA,U,CACA,0B,CPkKV,iD,CO5LM,Y,CP+LN,+C,CO9LM,c,CPiMN,sD,CO7LM,kB,CPgMN,sE,CAIA,4E,CO/LM,0B,CACE,4B,CPkMR,yD,COzLM,U,CP4LN,+D,CO1LQ,c,CACE,wB,CACA,S,CACA,U,CACA,0B,CP6LV,gD,COvNM,Y,CP0NN,8C,COzNM,c,CP4NN,qD,COxNM,kB,CP2NN,qE,CAIA,2E,CO1NM,0B,CACE,4B,CP6NR,wD,COpNM,U,CPuNN,8D,COrNQ,c,CACE,wB,CACA,S,CACA,U,CACA,0B,CPwNV,kD,COlPM,S,CPqPN,gD,COpPM,W,CPuPN,uD,COnPM,e,CPsPN,uE,CAIA,6E,COrPM,0B,CACE,4B,CPwPR,0D,CO/OM,U,CPkPN,gE,COhPQ,c,CACE,qB,CACA,S,CACA,U,CACA,uB,CPmPV,kD,CO7QM,Y,CPgRN,gD,CO7LE,qB,CACE,a,CACA,oB,CP8LJ,uD,CO9QM,kB,CPiRN,uE,CAIA,6E,COhRM,0B,CACE,4B,CPmRR,0D,CO1QM,U,CP6QN,gE,CO3QQ,c,CACE,wB,CACA,S,CACA,U,CACA,0B,CP8QV,uD,CO/PI,iB,CAEI,uB,CACA,U,CACA,S,CPiQR,0D,COzPM,e,CP4PN,gE,CO1PU,U,CACE,e,CACA,U,CACA,W,CACA,2C,CACA,uB,CP6PZ,4D,COzPM,Y,CACE,oB,CP4PR,kE,CO1PQ,Y,CP6PR,+D,COxPI,kB,CP2PJ,iD,COvPI,4B,CACE,a,CP+PN,sC,COnPE,U,CPsPF,gC,COlPE,iB,CACE,K,CACA,M,CPqPJ,iC,COjPE,iB,CACE,S,CACA,U,CACA,iB,CACA,wB,CACA,8B,CACA,e,CACA,iB,CPoPJ,sD,CO7OE,c,CACE,iC,CACA,e,CACA,c,CPgPJ,6D,CO7OI,W,CACE,e,CACA,iB,CPgPN,yC,CO3OE,yB,CACE,0B,CACA,uB,CP8OJ,wC,COzOI,S,CACE,U,CACA,U,CACA,wB,CACA,wC,CACA,U,CACA,iB,CACA,qB,CACA,W,CACA,Q,CACA,iB,CACA,S,CACA,8B,CP4ON,mD,CA6BA,iD,COrQI,S,CP2OJ,uC,COvOI,uB,CACE,kB,CACA,U,CACA,iB,CACA,wB,CACA,W,CACA,qB,CACA,iB,CACA,Q,CP0ON,0C,COxOM,S,CP2ON,2C,CO1OM,U,CP6ON,4C,CO5OM,S,CP+ON,+C,CO9OM,Y,CPiPN,4C,CO/OI,S,CPqPJ,oD,CO7OM,kB,CPiQN,kD,CAjBA,gD,CO9OI,Y,CPiPJ,4B,CO5OE,iB,CP+OF,gC,CO7OI,gC,CAEE,0B,CACA,W,CACA,U,CACA,uB,CP+ON,uC,CAAA,qC,CO5OM,sB,CACE,+B,CPkPR,mD,CO1OM,a,CP6ON,kD,COzOM,G,CACE,S,CP4OR,0C,COxOM,U,CP2ON,uC,COvOM,K,CACE,W,CP0OR,qC,COtOM,a,CACE,c,CACA,S,CPyOR,gD,COpOQ,kB,CAAO,U,CPwOf,8C,COvOQ,oB,CAAK,U,CP2Ob,+C,COvOQ,mB,CP0OR,6C,COzOQ,qB,CP4OR,gD,COxOQ,W,CP2OR,kD,COxOQ,S,CP2OR,2B,COpOE,c,CPuOF,2C,COpOI,qB,CACE,uB,CPuON,2C,COnOI,8B,CPqcJ,sD,CAAA,uD,CA/NA,iD,COpOM,W,CPuON,iC,COlOI,U,CACE,iB,CACA,iB,CACA,qB,CACA,uB,CACA,iB,CACA,yB,CACA,0B,CACA,uB,CPqON,+C,COjOQ,gC,CACE,qG,CPoOV,+C,COrOQ,gC,CACE,0G,CPwOV,qD,COzOQ,gC,CACE,gI,CP4OV,yC,COnOM,a,CACE,e,CACA,mB,CACA,yB,CACA,gC,CACA,wG,CP4OR,sD,COlOQ,c,CACE,a,CACA,iB,CACA,iB,CPqOV,gD,COjOQ,iB,CACE,S,CACA,W,CPoOV,sD,COlOU,e,CACE,kB,CACA,wB,CACA,W,CACA,U,CACA,W,CACA,c,CACA,iB,CACA,oB,CACA,e,CPqOZ,wD,COlOY,gB,CPqOZ,iE,COjOY,c,CACE,gB,CACA,gB,CACA,mD,CACA,kB,CACA,yB,CPoOd,+C,CO9NQ,iB,CACI,uB,CACA,yB,CPiOZ,0C,CO5NM,c,CACE,U,CP+NR,uD,CO5NQ,gB,CP+NR,wC,CO1NM,iB,CACE,wB,CACA,Y,CACA,S,CACA,oB,CACA,U,CACA,U,CP6NR,8C,CO1NQ,Y,CP6NR,8C,COzNQ,mB,CACE,e,CP4NV,sD,COzNU,iB,CACE,uB,CACA,kC,CACA,sB,CACA,uB,CACA,W,CACA,W,CACA,c,CACA,iB,CP4NZ,iD,COrNQ,U,CPwNR,uD,COtNU,c,CACE,qB,CACA,S,CACA,U,CACA,uB,CPyNZ,+C,COrNQ,Y,CPwNR,8C,COpNQ,W,CACE,e,CACA,W,CACA,U,CACA,mB,CACA,qB,CACA,uB,CPuNV,oD,COpNU,iB,CACE,yC,CPuNZ,oD,COjNU,e,CACE,kG,CACA,U,CACA,W,CACA,e,CACA,Q,CAEA,e,CPmNZ,sD,CO5MU,gB,CP+MV,sD,CO5MU,k1C,CACE,oB,CACA,U,CACA,W,CACA,Q,CAEA,e,CP8MZ,wC,CAAA,yC,COxMM,c,CP2MN,mD,CAAA,oD,COvMQ,mB,CP0MR,qD,CAAA,sD,COvMQ,kB,CP0MR,4C,COrMM,iB,CACE,U,CPwMR,6C,COrMM,iB,CACE,W,CACA,gB,CACA,gB,CPwMR,yC,COpMM,gB,CPuMN,+C,COrMQ,gB,CPwMR,wD,COpMQ,W,CACE,gB,CACA,iB,CPuMV,wC,COlMM,kB,CACE,e,CACA,kB,CPqMR,uD,COlMQ,U,CACE,gB,CPyMV,yE,CAJA,yE,COjMQ,uB,CAEE,Q,CPuMV,2D,COlMQ,yB,CPqMR,2C,COhMM,Y,CACE,sB,CACA,c,CACA,iB,CPmMR,kD,COjMQ,gB,CACE,e,CPoMV,wD,COlMU,a,CPyMV,uD,CAAA,wD,CO5LE,e,CP+LF,mD,CAAA,oD,CO5LE,yB,CPgMF,0C,CO3LA,mB","file":"blackprint.sf.css","sourcesContent":["/* Blackprint \n MIT Licensed */\nbpnode-header-info {\n  bottom: 24px;\n  position: relative;\n  padding: 5px 7px;\n  border-radius: 10px;\n  font-size: 16px;\n}\nbpnode-header-info.bphead-error {\n  box-shadow: 0 0 12px red;\n  border: 1px solid red;\n  background: rgba(255, 0, 0, 0.7803921569);\n}\nbpnode-header-info.bphead-info {\n  box-shadow: 0 0 12px white;\n  border: 1px solid white;\n  color: black;\n  background: rgba(255, 255, 255, 0.7803921569);\n}\nbpnode-header-info.bphead-warn {\n  box-shadow: 0 0 12px #fff700;\n  border: 1px solid #fff700;\n  background: rgba(255, 247, 0, 0.5882352941);\n  color: black;\n}\nbpnode-header-info.bphead-success {\n  box-shadow: 0 0 12px #62ff00;\n  background: rgba(98, 255, 0, 0.7803921569);\n  color: black;\n}\nsf-space[blackprint] .node comp-port-button .bp-button {\n  background: rgba(0, 0, 0, 0.5490196078);\n  border: 2px solid rgba(255, 255, 255, 0.4196078431);\n  margin: 3px;\n  padding: 2px 8px;\n  border-radius: 50px;\n  outline: none;\n  color: white;\n  cursor: pointer;\n}\nsf-space[blackprint] .node comp-port-button .bp-button:hover {\n  background: rgba(145, 145, 145, 0.5490196078);\n}\nsf-space[blackprint] .node .output > .ports comp-port-button.inline {\n  float: left;\n}\nsf-space[blackprint] .node .input > .ports comp-port-button.inline {\n  float: right;\n}\nsf-space[blackprint] .node comp-port-input input {\n  display: inline-block;\n  max-width: 30px;\n  background: rgba(0, 0, 0, 0.6588235294);\n  color: white;\n  border: 1px solid gray;\n  border-radius: 5px;\n}\nsf-space[blackprint] .node comp-port-input.size-2 {\n  display: block;\n  margin-bottom: 10px;\n}\nsf-space[blackprint] .node comp-port-input.size-2 input {\n  max-width: 120px;\n}\nsf-space[blackprint] .node comp-port-textarea textarea {\n  max-width: 40px;\n  max-height: 15px;\n  margin-left: 0px;\n  border: 1px solid rgba(85, 255, 82, 0.5490196078);\n  box-shadow: 0 0 2px rgba(85, 255, 82, 0.5490196078);\n  border-radius: 5px;\n  padding: 1px 2px;\n  vertical-align: middle;\n  resize: none;\n  white-space: pre;\n}\nsf-space[blackprint] .node comp-port-textarea textarea::-webkit-scrollbar {\n  width: 4px;\n  height: 4px;\n}\nsf-space[blackprint] .node comp-port-textarea.size-2 {\n  display: block;\n  margin-bottom: 10px;\n}\nsf-space[blackprint] .node comp-port-textarea.size-2 textarea {\n  max-width: unset;\n  max-height: unset;\n  resize: both;\n}\nsf-space[blackprint] .bp-dropdown-menu {\n  z-index: 10000;\n  opacity: 0.9;\n  margin-top: 7px;\n  background-color: rgba(255, 255, 255, 0.96);\n  box-shadow: 1px 1px 11px 3px black;\n  border: inherit;\n  position: fixed;\n  top: 0;\n  left: 0;\n  padding: 0;\n  border-radius: 3px;\n  background: white;\n}\nsf-space[blackprint] .bp-dropdown-menu.hidden {\n  visibility: hidden;\n  opacity: 0;\n}\nsf-space[blackprint] .bp-dropdown-menu input {\n  display: none;\n  outline: none;\n  border: none;\n  border-bottom: 1px solid black;\n  width: calc(100% - 4px);\n  font-family: \"Nunito\", sans-serif, \"Font Awesome 5 Free\";\n}\nsf-space[blackprint] .bp-dropdown-menu input::placeholder {\n  text-align: center;\n}\nsf-space[blackprint] .bp-dropdown-menu ul {\n  overflow-x: hidden;\n  overflow-y: auto;\n  max-height: 300px;\n}\nsf-space[blackprint] .bp-dropdown-menu li {\n  position: relative;\n  vertical-align: baseline;\n  display: inherit !important;\n  padding: 8px 16px 8px 8px;\n  min-width: 110px;\n  border-bottom: 1px dashed darkgray;\n  font-size: 16px;\n  max-width: 400px;\n  cursor: pointer;\n  color: black;\n}\nsf-space[blackprint] .bp-dropdown-menu li.has-desc {\n  padding: 2px 16px 2px 8px;\n}\nsf-space[blackprint] .bp-dropdown-menu li.has-desc a {\n  display: block;\n}\nsf-space[blackprint] .bp-dropdown-menu li.has-desc .title {\n  font-size: 14px;\n}\nsf-space[blackprint] .bp-dropdown-menu li .description {\n  font-size: 12px;\n  color: gray;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\nsf-space[blackprint] .bp-dropdown-menu li > * {\n  pointer-events: none;\n}\nsf-space[blackprint] .bp-dropdown-menu li:hover {\n  background: lightgray;\n}\nsf-space[blackprint] .bp-dropdown-menu li li > a > span {\n  padding-right: 6px;\n}\nsf-space[blackprint] ul li .has-deep {\n  top: 11px;\n  position: absolute;\n  right: 5px;\n}\nsf-space[blackprint] sf-m[name=dropdown].has-search > drop-down > input {\n  display: block;\n}\nsf-space[blackprint] drop-down.bp-dropdown-menu drop-down {\n  opacity: 1;\n}\nsf-space[blackprint] drop-down > .first {\n  display: block;\n  padding: 5px 10px;\n  text-align: center;\n  font-weight: bold;\n  font-size: 16px;\n  text-transform: capitalize;\n  letter-spacing: 1px;\n  color: white;\n  background: #ba2f63;\n  box-shadow: 0 0 5px #d12867;\n}\nsf-space[blackprint] drop-down ul {\n  margin: 0;\n  padding: 0;\n}\nsf-space[blackprint] drop-down ul li a {\n  display: flex;\n}\nsf-space[blackprint] drop-down ul li a div {\n  padding-left: 5px;\n}\nsf-space[blackprint] drop-down ul .dropdown-icon {\n  padding-right: 5px;\n  float: left;\n  align-self: center;\n}\nsf-space[blackprint] drop-down ul li.disabled, sf-space[blackprint] drop-down ul li.disabled:hover {\n  cursor: default !important;\n  background: #888;\n}\nsf-space[blackprint] .nodes bpic-bp-env-get .content .center, sf-space[blackprint] .nodes bpic-bp-env-set .content .center,\nsf-space[blackprint] .nodes bpic-bp-var-get .content .center, sf-space[blackprint] .nodes bpic-bp-var-set .content .center,\nsf-space[blackprint] .nodes bpic-bp-fnvar-input .content .center, sf-space[blackprint] .nodes bpic-bp-fnvar-output .content .center {\n  text-align: center;\n  background: rgba(0, 243, 255, 0.3019607843);\n  display: inline-block;\n  padding: 4px 12px;\n  border-radius: 5px;\n  font-size: 15px;\n}\nsf-space[blackprint] .nodes bpic-bp-env-get .content .center .description, sf-space[blackprint] .nodes bpic-bp-env-set .content .center .description,\nsf-space[blackprint] .nodes bpic-bp-var-get .content .center .description, sf-space[blackprint] .nodes bpic-bp-var-set .content .center .description,\nsf-space[blackprint] .nodes bpic-bp-fnvar-input .content .center .description, sf-space[blackprint] .nodes bpic-bp-fnvar-output .content .center .description {\n  font-size: 12px;\n  color: darkgray;\n}\nsf-space[blackprint] .nodes bpic-bp-env-get .content .ports, sf-space[blackprint] .nodes bpic-bp-env-set .content .ports,\nsf-space[blackprint] .nodes bpic-bp-var-get .content .ports, sf-space[blackprint] .nodes bpic-bp-var-set .content .ports,\nsf-space[blackprint] .nodes bpic-bp-fnvar-input .content .ports, sf-space[blackprint] .nodes bpic-bp-fnvar-output .content .ports {\n  margin-top: 10px;\n}\nsf-space[blackprint] .nodes bpic-bp-env-get .content .ports > div.name, sf-space[blackprint] .nodes bpic-bp-env-set .content .ports > div.name,\nsf-space[blackprint] .nodes bpic-bp-var-get .content .ports > div.name, sf-space[blackprint] .nodes bpic-bp-var-set .content .ports > div.name,\nsf-space[blackprint] .nodes bpic-bp-fnvar-input .content .ports > div.name, sf-space[blackprint] .nodes bpic-bp-fnvar-output .content .ports > div.name {\n  display: none;\n}\nsf-space[blackprint] .nodes bpic-bp-fnvar-input .content .center, sf-space[blackprint] .nodes bpic-bp-fnvar-output .content .center {\n  background: rgba(121, 53, 165, 0.8);\n}\nsf-space[blackprint] .nodes bpic-bp-env-get .content .center, sf-space[blackprint] .nodes bpic-bp-var-get .content .center, sf-space[blackprint] .nodes bpic-bp-fnvar-input .content .center {\n  margin-left: -25px;\n  margin-right: -15px;\n}\nsf-space[blackprint] .nodes bpic-bp-env-set .content .center, sf-space[blackprint] .nodes bpic-bp-var-set .content .center, sf-space[blackprint] .nodes bpic-bp-fnvar-output .content .center {\n  margin-left: -15px;\n  margin-right: -25px;\n}\nsf-m {\n  display: block;\n}\n\nsf-space[blackprint] {\n  position: absolute;\n}\nsf-space[blackprint] sf-m[name=container] > .select {\n  background: rgba(82, 159, 255, 0.2509803922);\n  outline: 1px solid #0095ff;\n  position: absolute;\n  backface-visibility: hidden;\n  top: 0;\n  left: 0;\n  display: block;\n  transform-origin: top left;\n}\nsf-space[blackprint] sf-m[name=container] > .select.hide {\n  display: none;\n}\nsf-space[blackprint], sf-space[blackprint] .nodes, sf-space[blackprint] .cables {\n  height: 100%;\n  width: 100%;\n  display: block;\n}\nsf-space[blackprint] .description {\n  margin-top: 3px;\n  white-space: pre-line;\n}\nsf-space[blackprint] .node textarea, sf-space[blackprint] .node input {\n  background: rgba(0, 0, 0, 0.63);\n  color: white;\n  border: none;\n}\nsf-space[blackprint] .node textarea {\n  margin: 0px 5px 0px -10px;\n}\nsf-space[blackprint] .node select {\n  background: #232323;\n  color: white;\n  border: 1px solid #6d6d6d;\n}\nsf-space[blackprint] .node.input textarea {\n  margin-left: 5px;\n  margin-right: -10px;\n}\nsf-space[blackprint] .nodes .node.bp-skeleton {\n  min-width: 200px;\n}\nsf-space[blackprint] .nodes .node.bp-skeleton .header .description {\n  max-width: 200px;\n  font-size: 14px;\n  font-style: normal;\n}\nsf-space[blackprint] .nodes .node.bp-skeleton .input {\n  padding-right: 5px;\n}\nsf-space[blackprint] .nodes .node.bp-skeleton .right-port {\n  margin-left: 5px;\n}\nsf-space[blackprint] .nodes .node.bp-skeleton .ports.ArrayOf > .port {\n  background: white;\n}\nsf-space[blackprint] .nodes .node.bp-skeleton .ports.ArrayOf > .port:before {\n  content: unset;\n}\nsf-space[blackprint] .BP-Hide {\n  display: none;\n}\nsf-space[blackprint] .BP-AllowResync {\n  color: yellow;\n}\nsf-space[blackprint] .cables > svg > g.Number circle {\n  fill: #00bfff;\n}\nsf-space[blackprint] .cables > svg > g.Number path {\n  stroke: #00bfff;\n}\nsf-space[blackprint] .nodes .node .ports.Number > .port {\n  background: #00bfff;\n}\nsf-space[blackprint] .nodes .node .ports.Number comp-port-input input {\n  border: 1px solid #00bfff8c;\n  box-shadow: 0 0 2px #00bfff8c;\n}\nsf-space[blackprint] .nodes .node .ports.Number comp-port-textarea textarea {\n  border: 1px solid #00bfff8c;\n  box-shadow: 0 0 2px #00bfff8c;\n}\nsf-space[blackprint] .nodes .node .ports.Number.inactive {\n  color: grey;\n}\nsf-space[blackprint] .nodes .node .ports.Number.inactive > .port {\n  background: transparent;\n  border: 2px solid #00bfff;\n  width: 8px;\n  height: 8px;\n  box-shadow: 0 0 4px #00bfff;\n}\nsf-space[blackprint] .cables > svg > g.Object circle {\n  fill: #9370db;\n}\nsf-space[blackprint] .cables > svg > g.Object path {\n  stroke: #9370db;\n}\nsf-space[blackprint] .nodes .node .ports.Object > .port {\n  background: #9370db;\n}\nsf-space[blackprint] .nodes .node .ports.Object comp-port-input input {\n  border: 1px solid #9370db8c;\n  box-shadow: 0 0 2px #9370db8c;\n}\nsf-space[blackprint] .nodes .node .ports.Object comp-port-textarea textarea {\n  border: 1px solid #9370db8c;\n  box-shadow: 0 0 2px #9370db8c;\n}\nsf-space[blackprint] .nodes .node .ports.Object.inactive {\n  color: grey;\n}\nsf-space[blackprint] .nodes .node .ports.Object.inactive > .port {\n  background: transparent;\n  border: 2px solid #9370db;\n  width: 8px;\n  height: 8px;\n  box-shadow: 0 0 4px #9370db;\n}\nsf-space[blackprint] .cables > svg > g.Boolean circle {\n  fill: #ff5959;\n}\nsf-space[blackprint] .cables > svg > g.Boolean path {\n  stroke: #ff5959;\n}\nsf-space[blackprint] .nodes .node .ports.Boolean > .port {\n  background: #ff5959;\n}\nsf-space[blackprint] .nodes .node .ports.Boolean comp-port-input input {\n  border: 1px solid #ff59598c;\n  box-shadow: 0 0 2px #ff59598c;\n}\nsf-space[blackprint] .nodes .node .ports.Boolean comp-port-textarea textarea {\n  border: 1px solid #ff59598c;\n  box-shadow: 0 0 2px #ff59598c;\n}\nsf-space[blackprint] .nodes .node .ports.Boolean.inactive {\n  color: grey;\n}\nsf-space[blackprint] .nodes .node .ports.Boolean.inactive > .port {\n  background: transparent;\n  border: 2px solid #ff5959;\n  width: 8px;\n  height: 8px;\n  box-shadow: 0 0 4px #ff5959;\n}\nsf-space[blackprint] .cables > svg > g.String circle {\n  fill: #55ff52;\n}\nsf-space[blackprint] .cables > svg > g.String path {\n  stroke: #55ff52;\n}\nsf-space[blackprint] .nodes .node .ports.String > .port {\n  background: #55ff52;\n}\nsf-space[blackprint] .nodes .node .ports.String comp-port-input input {\n  border: 1px solid #55ff528c;\n  box-shadow: 0 0 2px #55ff528c;\n}\nsf-space[blackprint] .nodes .node .ports.String comp-port-textarea textarea {\n  border: 1px solid #55ff528c;\n  box-shadow: 0 0 2px #55ff528c;\n}\nsf-space[blackprint] .nodes .node .ports.String.inactive {\n  color: grey;\n}\nsf-space[blackprint] .nodes .node .ports.String.inactive > .port {\n  background: transparent;\n  border: 2px solid #55ff52;\n  width: 8px;\n  height: 8px;\n  box-shadow: 0 0 4px #55ff52;\n}\nsf-space[blackprint] .cables > svg > g.BP-Union circle {\n  fill: #ffffff;\n}\nsf-space[blackprint] .cables > svg > g.BP-Union path {\n  stroke: #ffffff;\n}\nsf-space[blackprint] .nodes .node .ports.BP-Union > .port {\n  background: #ffffff;\n}\nsf-space[blackprint] .nodes .node .ports.BP-Union comp-port-input input {\n  border: 1px solid #ffffff8c;\n  box-shadow: 0 0 2px #ffffff8c;\n}\nsf-space[blackprint] .nodes .node .ports.BP-Union comp-port-textarea textarea {\n  border: 1px solid #ffffff8c;\n  box-shadow: 0 0 2px #ffffff8c;\n}\nsf-space[blackprint] .nodes .node .ports.BP-Union.inactive {\n  color: grey;\n}\nsf-space[blackprint] .nodes .node .ports.BP-Union.inactive > .port {\n  background: transparent;\n  border: 2px solid #ffffff;\n  width: 8px;\n  height: 8px;\n  box-shadow: 0 0 4px #ffffff;\n}\nsf-space[blackprint] .cables > svg > g.BP-Route circle {\n  fill: #ffac7b;\n}\nsf-space[blackprint] .cables > svg > g.BP-Route path {\n  stroke: #ffac7b;\n}\nsf-space[blackprint] .nodes .node .ports.BP-Route > .port {\n  background: #ffac7b;\n}\nsf-space[blackprint] .nodes .node .ports.BP-Route comp-port-input input {\n  border: 1px solid #ffac7b8c;\n  box-shadow: 0 0 2px #ffac7b8c;\n}\nsf-space[blackprint] .nodes .node .ports.BP-Route comp-port-textarea textarea {\n  border: 1px solid #ffac7b8c;\n  box-shadow: 0 0 2px #ffac7b8c;\n}\nsf-space[blackprint] .nodes .node .ports.BP-Route.inactive {\n  color: grey;\n}\nsf-space[blackprint] .nodes .node .ports.BP-Route.inactive > .port {\n  background: transparent;\n  border: 2px solid #ffac7b;\n  width: 8px;\n  height: 8px;\n  box-shadow: 0 0 4px #ffac7b;\n}\nsf-space[blackprint] .nodes .node .ports.BP-Route > .port {\n  border-radius: 2px;\n  transform: rotate(45deg);\n  height: 8px;\n  width: 8px;\n}\nsf-space[blackprint] .nodes .node .ports.BP-StructOf > .port {\n  overflow: hidden;\n}\nsf-space[blackprint] .nodes .node .ports.BP-StructOf > .port:after {\n  content: \"\";\n  background: #ffffff;\n  width: 100%;\n  height: 100%;\n  transform: translate(4px, -4px) rotate(45deg);\n  outline: 2px black dashed;\n}\nsf-space[blackprint] .nodes .node .ports.BP-StructOf.BP-Open {\n  display: none;\n  margin: 10px 10px 0 0;\n}\nsf-space[blackprint] .nodes .node .ports.BP-StructOf.BP-Open .port {\n  display: none;\n}\nsf-space[blackprint] .nodes .node .ports.BP-StructSplit.BP-Last {\n  margin-bottom: 10px;\n}\nsf-space[blackprint] .nodes .node .ports.disabled {\n  text-decoration: line-through;\n  color: #727272;\n}\nsf-space[blackprint] .cables > svg > g.BP-Route path {\n  stroke-dasharray: 10px;\n  stroke: orange;\n  stroke-linecap: round;\n}\nsf-space[blackprint] .cables .inactive {\n  opacity: 0.4;\n}\nsf-space[blackprint] .glow-cable {\n  position: absolute;\n  top: 0;\n  left: 0;\n}\nsf-space[blackprint] .bp-dot-glow {\n  position: absolute;\n  width: 8px;\n  height: 8px;\n  border-radius: 5px;\n  box-shadow: 0 0 10px yellow;\n  transform: translate(-5px, -5px);\n  background: yellow;\n  visibility: hidden;\n}\nsf-space[blackprint] .nodes .node .ports.ArrayOf > .port {\n  background: none;\n  font-family: \"Font Awesome 5 Free\";\n  font-weight: 900;\n  font-size: 12px;\n}\nsf-space[blackprint] .nodes .node .ports.ArrayOf > .port:before {\n  content: \"\\f00a\";\n  margin-top: -1px;\n  position: absolute;\n}\nsf-space[blackprint] sf-m[name=container] {\n  transform-origin: top left;\n  backface-visibility: hidden;\n  touch-action: pinch-zoom;\n}\nsf-space[blackprint] .nodes .node:before {\n  left: -1px;\n  z-index: -1;\n  content: \"\";\n  box-shadow: 0px 0px 20px white;\n  background: rgba(255, 255, 255, 0.0705882353);\n  width: 100%;\n  border-radius: 6px;\n  border: 1px solid black;\n  height: 100%;\n  top: -1px;\n  position: absolute;\n  opacity: 0;\n  transition: opacity 0.3s ease-in;\n}\nsf-space[blackprint] .nodes .highlight .node:before {\n  opacity: 1;\n}\nsf-space[blackprint] .nodes .routes div {\n  transform: rotate(45deg);\n  background: #ffac7b;\n  width: 10px;\n  border-radius: 3px;\n  box-shadow: 0 0 3px 0 black;\n  height: 10px;\n  border: 1px solid black;\n  position: absolute;\n  top: -7px;\n}\nsf-space[blackprint] .nodes .routes div.in {\n  left: -7px;\n}\nsf-space[blackprint] .nodes .routes div.out {\n  right: -7px;\n}\nsf-space[blackprint] .nodes .routes div.hide {\n  opacity: 0;\n}\nsf-space[blackprint] .nodes .routes div.disable {\n  display: none;\n}\nsf-space[blackprint] .nodes .routes.show div {\n  z-index: 1;\n}\nsf-space[blackprint] .nodes .routes.show div.hide {\n  opacity: 1;\n}\nsf-space[blackprint] .nodes .routes.no-update div.in {\n  background: #727272;\n}\nsf-space[blackprint] .nodes .routes.disabled div {\n  display: none;\n}\nsf-space[blackprint] .cables {\n  position: absolute;\n}\nsf-space[blackprint] .cables > svg {\n  filter: drop-shadow(0 0 2px black);\n  backface-visibility: hidden;\n  height: 100%;\n  width: 100%;\n  transform: translateZ(0px);\n}\nsf-space[blackprint] .cables > svg path, sf-space[blackprint] .cables > svg circle {\n  transition: 0.1s ease-in;\n  transition-property: stroke, fill;\n}\nsf-space[blackprint] .cables > svg .connected circle {\n  display: none;\n}\nsf-space[blackprint] .cables > svg .has-branch circle {\n  display: block;\n}\nsf-space[blackprint] .cables > svg g.selected circle {\n  r: 8;\n  fill: white;\n}\nsf-space[blackprint] .cables > svg .disabled {\n  opacity: 0.4;\n}\nsf-space[blackprint] .cables > svg circle {\n  r: 5px;\n  fill: orange;\n}\nsf-space[blackprint] .cables > svg path {\n  stroke: orange;\n  stroke-width: 3;\n  fill: none;\n}\nsf-space[blackprint] .cables > svg .invalid circle {\n  fill: red !important;\n  opacity: 0.6;\n}\nsf-space[blackprint] .cables > svg .invalid path {\n  stroke: red !important;\n  opacity: 0.6;\n}\nsf-space[blackprint] .cables > svg g:hover circle {\n  fill: white !important;\n}\nsf-space[blackprint] .cables > svg g:hover path {\n  stroke: white !important;\n}\nsf-space[blackprint] .cables > svg .highlight path {\n  stroke: white;\n}\nsf-space[blackprint] .cables > svg .highlight circle {\n  fill: white;\n}\nsf-space[blackprint] .nodes {\n  position: unset;\n}\nsf-space[blackprint] .nodes .selected .node {\n  border: 1px solid white;\n  box-shadow: 0 0 5px white;\n}\nsf-space[blackprint] .nodes .inactive .node {\n  filter: saturate(0) opacity(0.7);\n}\nsf-space[blackprint] .nodes .inactive .node:hover {\n  filter: none;\n}\nsf-space[blackprint] .nodes .node {\n  color: white;\n  font-family: Arial;\n  border-radius: 5px;\n  border: 1px solid black;\n  box-shadow: 0 0 5px black;\n  position: absolute;\n  background: rgba(0, 0, 0, 0.7);\n  backface-visibility: hidden;\n  transform: translateZ(0px);\n}\nsf-space[blackprint] .nodes .node.event .header {\n  box-shadow: inset 0 0 3px #a05f5f;\n  background: linear-gradient(120deg, rgba(226, 18, 18, 0.7) 0%, rgba(229, 41, 41, 0.2) 80%, rgba(229, 32, 32, 0.1) 100%);\n}\nsf-space[blackprint] .nodes .node.input .header {\n  box-shadow: inset 0 0 3px #75a05f;\n  background: linear-gradient(120deg, rgba(108, 232, 93, 0.7) 0%, rgba(103, 255, 108, 0.2) 80%, rgba(130, 226, 124, 0.1) 100%);\n}\nsf-space[blackprint] .nodes .node.func-in-out .header {\n  box-shadow: inset 0 0 3px #b030ff;\n  background: linear-gradient(120deg, rgba(150, 0, 199, 0.7019607843) 0%, rgba(66, 0, 106, 0.7019607843) 80%, rgba(131, 50, 219, 0.7019607843) 100%);\n}\nsf-space[blackprint] .nodes .node .header {\n  display: block;\n  text-align: left;\n  padding: 3px 5px 2px 5px;\n  border-radius: 5px 5px 0 0;\n  box-shadow: inset 0 0 3px cadetblue;\n  background: linear-gradient(120deg, rgba(41, 184, 229, 0.7) 0%, rgba(41, 184, 229, 0.2) 80%, rgba(32, 124, 229, 0.1) 100%);\n  /*linear-gradient(160deg, rgba(41,184,229,0.7) 0%, rgba(41,184,229,0.2) 54%, rgba(32,124,229,0.1) 80%, rgba(32,124,229,0.2) 100%)\n\n  -webkit-gradient(\n    linear, left top, right bottom, from(rgba(41,184,229,0.7)),\n    to(rgba(41,184,229,0.2)), color-stop(.8,rgba(32,124,229,0.1))\n  );*/\n}\nsf-space[blackprint] .nodes .node .header .description {\n  font-size: 12px;\n  color: darkgray;\n  padding-right: 5px;\n  font-style: italic;\n}\nsf-space[blackprint] .nodes .node .header .extra {\n  position: absolute;\n  top: -12px;\n  right: -10px;\n}\nsf-space[blackprint] .nodes .node .header .extra .item {\n  background: black;\n  border-radius: 50px;\n  box-shadow: 0 0 11px white;\n  height: 20px;\n  width: 20px;\n  padding: 2px;\n  font-size: 12px;\n  text-align: center;\n  display: inline-block;\n  margin-left: 5px;\n}\nsf-space[blackprint] .nodes .node .header .extra .item i {\n  line-height: 21px;\n}\nsf-space[blackprint] .nodes .node .header .extra .item.node-route {\n  font-size: 15px;\n  line-height: 20px;\n  margin-left: 10px;\n  box-shadow: 0 0 17px 5px rgba(255, 141, 0, 0.8901960784);\n  background: #53340e;\n  outline: 2px solid #ff8d00;\n}\nsf-space[blackprint] .nodes .node .header.small {\n  position: absolute;\n  height: calc(100% - 5px);\n  border-radius: 5px 0 0 5px;\n}\nsf-space[blackprint] .nodes .node .content {\n  display: inline;\n  width: 100%;\n}\nsf-space[blackprint] .nodes .node .content.header-small {\n  margin-left: 32px;\n}\nsf-space[blackprint] .nodes .node .other {\n  position: absolute;\n  bottom: calc(100% - 15px);\n  display: grid;\n  left: -1px;\n  justify-items: center;\n  right: -1px;\n  z-index: -1;\n}\nsf-space[blackprint] .nodes .node .other .list {\n  display: grid;\n}\nsf-space[blackprint] .nodes .node .other .item {\n  display: inline-flex;\n  margin-top: 10px;\n}\nsf-space[blackprint] .nodes .node .other .item.comment {\n  border-radius: 5px;\n  width: calc(100% - 12px);\n  background: rgba(0, 0, 0, 0.6196078431);\n  outline: 1px solid black;\n  box-shadow: 0 0 5px white;\n  padding: 5px;\n  bottom: 25px;\n  font-size: 14px;\n  position: relative;\n}\nsf-space[blackprint] .nodes .node .ports.inactive {\n  color: grey;\n}\nsf-space[blackprint] .nodes .node .ports.inactive > .port {\n  background: transparent;\n  border: 2px solid white;\n  width: 8px;\n  height: 8px;\n  box-shadow: 0 0 4px white;\n}\nsf-space[blackprint] .nodes .node .ports.unused {\n  display: none;\n}\nsf-space[blackprint] .nodes .node .ports .port {\n  z-index: 200;\n  background: white;\n  height: 10px;\n  width: 10px;\n  border-radius: 100px;\n  border: 1px solid black;\n  box-shadow: 0 0 5px black;\n}\nsf-space[blackprint] .nodes .node .ports .port.event {\n  border-radius: 2px;\n  transform: rotate(45deg) skew(10deg, 10deg);\n}\nsf-space[blackprint] .nodes .node .ports._Exec .port {\n  background: white;\n  clip-path: path(\"M 0 0 L 6 0 C 8 1 12 5 12 6 C 12 7 8 11 6 12 L 0 12 C 3 9 2 10 5 6 C 3 3 2 2 0 0\");\n  width: 12px;\n  height: 12px;\n  border-radius: 0;\n  border: none;\n  box-shadow: none;\n}\nsf-space[blackprint] .nodes .node .ports.Trigger .name {\n  line-height: 20px;\n}\nsf-space[blackprint] .nodes .node .ports.Trigger .port {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAYAAADE6YVjAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuMTM0A1t6AAADUUlEQVRIS7WWXUhTYRjH3Waf2gdUEmYhgRUEIcIkcywmCHrRjS5Q8GZahA5CglHsrrvUlAkLvBh1I12UiGAwbzYU/EIvRpgiBc27BEHNLMdmPv3/Z2eb284+gnrgN97z/J/nffa+5z3POQUiEgemB0dBMSgBV8EtYFThmD5qjGGs/vAcWiQG0QJHwCmdTlcGqsA9XHeAxyod9KlaGWMBc7IWiv4kChQj+bJer68BNvAC12/h/0A4pk/VahjLHDVXlzp5DJoOFIIiJF1C8h2DwdAJPCaT6aPf7/+5t7d3QDimjxpjGMsc5J4EBs6VqQjFE6AECVVI7MAEr20229dIJIKYZKPP4XBIe3u7eDweGR4efoncC+AY0Nw2GsWz4BoKNANXdXX1UigUOkCApkGTlpYW6e7ulpGREfF6vc+Rz/tTCFmzSBEoxSpMKOAA3snJyRDErDY1NSWNjY3S29srMzMz+/Pz8+2Yh384bctoXEUFijQDt9Fo/AwhL2tqahK73S5jY2MSDAYja2trzZgrbcto50EleATe4599h5CXuVwusVqtyr1ZWVmRnZ2dXWCGlFbkIqgBT4B3dnY2DCEvm5ubk4aGBhkcHJRAICDb29sSDod/QKoESUVKgQk8A7719fXfEPIyxEpdXZ309fXJ4uKibG1tKacP9g3cAPEiPOdm4AR+RvyNWSwW6enpkYWFBdnc3ORKVEUC4L8WSVtJ0nZtbGxkfD5SDbFp25XpnvyzG48iu1jNXUjxAoSWdIQHBgbyPsJutzt+hJeXl/dXV1fvYw4DpLQihx/GV2az+QuEvKy1tVW6urpkdHR0f3x8vBPzsFFqPoypbWVieno6Z1tBK1G2im1laGioH3PEmqRmW1EaJIpcRwGlQdbW1n7K1SDb2tqUBul0Ot8gtwJzKA0SaBZJbfUP1FYfzNTqqTGGscxBbs5Wn/GlVV9fv+Tz+X7FXloc00eNMYxlDnKzv7SUn8Trl+/3K0jm/XkI+nH9Dv4JwjF9qmZiLHPUXM0CJDGIFuLXxxkkl4PbwIprO3iqYqdP1coZC3J+sSQG0W3jko8DHmt+jdwEfFAtKhzTR40xjM24TTEU03DGto8H4jQ4B/itRTimjxpjsq5CRAr+AGaARw6hXaKlAAAAAElFTkSuQmCC);\n  background-size: 20px;\n  width: 20px;\n  height: 20px;\n  border: none;\n  box-shadow: none;\n}\nsf-space[blackprint] .nodes .node .output, sf-space[blackprint] .nodes .node .input {\n  margin-top: 1px;\n}\nsf-space[blackprint] .nodes .node .output .ports > div, sf-space[blackprint] .nodes .node .input .ports > div {\n  display: inline-flex;\n}\nsf-space[blackprint] .nodes .node .output .ports > .name, sf-space[blackprint] .nodes .node .input .ports > .name {\n  margin: 0 3px 0 5px;\n}\nsf-space[blackprint] .nodes .node .left-port {\n  position: relative;\n  float: left;\n}\nsf-space[blackprint] .nodes .node .right-port {\n  position: relative;\n  float: right;\n  text-align: right;\n  margin-left: 20px;\n}\nsf-space[blackprint] .nodes .node .output {\n  margin-right: 5px;\n}\nsf-space[blackprint] .nodes .node .output .name {\n  text-align: right;\n}\nsf-space[blackprint] .nodes .node .output .Trigger .port {\n  float: right;\n  margin-left: -1px;\n  margin-right: -5px;\n}\nsf-space[blackprint] .nodes .node .input {\n  padding-right: 20px;\n  margin-left: 5px;\n  white-space: nowrap;\n}\nsf-space[blackprint] .nodes .node .input .Trigger .port {\n  float: left;\n  margin-left: -2px;\n}\nsf-space[blackprint] .nodes .node .input input::-webkit-outer-spin-button,\nsf-space[blackprint] .nodes .node .input input::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\nsf-space[blackprint] .nodes .node .input {\n  /* Firefox */\n}\nsf-space[blackprint] .nodes .node .input input[type=number] {\n  -moz-appearance: textfield;\n}\nsf-space[blackprint] .nodes .node .property {\n  display: flex;\n  justify-content: center;\n  margin-top: 5px;\n  margin-bottom: 5px;\n}\nsf-space[blackprint] .nodes .node .property .ports {\n  margin-right: 8px;\n  margin-left: 8px;\n}\nsf-space[blackprint] .nodes .node .property .ports .port {\n  margin: 0 auto;\n}\n\nbody.blackprint-no-vfx sf-space[blackprint] .cables > svg, body sf-space[blackprint] .importing-nodes .cables > svg {\n  filter: none;\n}\nbody.blackprint-no-vfx sf-space[blackprint] .nodes .node, body sf-space[blackprint] .importing-nodes .nodes .node {\n  transition: none;\n}\nbody.blackprint-no-vfx sf-space[blackprint] .nodes *, body sf-space[blackprint] .importing-nodes .nodes * {\n  box-shadow: none !important;\n}\n\nbody sf-space[blackprint] .importing-nodes {\n  pointer-events: none;\n}\n\n/*# sourceMappingURL=blackprint.sf.css.map */","## html\n<bpnode-header-info class=\"bphead-{{ type }}\" title=\"{{ description }}\">{{ text }}</bpnode-header-info>\n\n## scss-global\nbpnode-header-info {\n\tbottom: 24px;\n\tposition: relative;\n\tpadding: 5px 7px;\n\tborder-radius: 10px;\n\tfont-size: 16px;\n\n\t&.bphead-error{\n\t\tbox-shadow: 0 0 12px red;\n\t\tborder: 1px solid red;\n\t\tbackground: #ff0000c7;\n\t}\n\n\t&.bphead-info{\n\t\tbox-shadow: 0 0 12px white;\n\t\tborder: 1px solid white;\n\t\tcolor: black;\n\t\tbackground: #ffffffc7;\n\t}\n\n\t&.bphead-warn{\n\t\tbox-shadow: 0 0 12px #fff700;\n\t\tborder: 1px solid #fff700;\n\t\tbackground: #fff70096;\n\t\tcolor: black;\n\t}\n\n\t&.bphead-success{\n\t\tbox-shadow: 0 0 12px #62ff00;\n\t\tbackground: #62ff00c7;\n\t\tcolor: black;\n\t}\n}\n\n## js-global\nBlackprint.space.component('bpnode-header-info', {\n\ttemplate: #this.path\n}, function(My){\n\tMy.type = \"info\";\n\tMy.text = \"\";\n\tMy.description = \"\";\n\n\t// Mark this element as cloneable for Blackprint Sketch\n\tMy.$cloneable = true;\n});","## html\n<comp-port-button style=\"display: {{ visible ? '' : 'none' }}\" class=\"{{ inline ? 'inline' : '' }}\">\n\t<div class=\"bp-button\" @click=\"click(event)\" @pointerdown.capture.stop=\"press(event)\" @pointerup=\"release(event)\" title=\"{{ tooltip }}\">{{ text }}</div>\n</comp-port-button>\n\n\n## js-global\nBlackprint.space.component('comp-port-button', {\n\ttemplate: #this.path, // 'Blackprint/component/comp-port-button.sf'\n\textend: class extends sf.Model {\n\t\tasync beforeInit(){\n\t\t\tlet noData = this.noData = this.which == null;\n\n\t\t\tthis.inline ??= false;\n\t\t\tthis.visible ??= true;\n\t\t\tthis.text ??= \"Button\";\n\t\t\tthis.tooltip ??= \"\";\n\t\t}\n\n\t\tclick(ev){\n\t\t\tif(this.onClick) return this.onClick(ev);\n\t\t}\n\n\t\tpress(ev){\n\t\t\tif(this.onPress) return this.onPress(ev);\n\t\t}\n\n\t\trelease(ev){\n\t\t\tif(this.onRelease) return this.onRelease(ev);\n\t\t}\n\t}\n}, ()=> {});\n\n\n## scss-global\nsf-space[blackprint]{\n\t.node comp-port-button {\n\t\t.bp-button {\n            background: #0000008c;\n            border: 2px solid #ffffff6b;\n            margin: 3px;\n            padding: 2px 8px;\n            border-radius: 50px;\n            outline: none;\n            color: white;\n            cursor: pointer;\n            &:hover{\n                background: #9191918c;\n            }\n        }\n\t}\n\n    .node .output > .ports {\n        comp-port-button {\n            &.inline {\n                float: left;\n            }\n        }\n    }\n\n    .node .input > .ports {\n        comp-port-button {\n            &.inline {\n                float: right;\n            }\n        }\n    }\n}","## html\n<comp-port-input style=\"display: {{ visible ? '' : 'none' }}\" class=\"{{ _size }}\">\n\t<input @pointerdown=\"click\" @pointerup=\"click\" type=\"{{ type }}\" sf-bind=\"value\">\n</comp-port-input>\n\n\n## js-global\nBlackprint.space.component('comp-port-input', {\n\ttemplate: #this.path, // 'Blackprint/component/comp-port-input.sf'\n\textend: class extends sf.Model {\n\t\tasync beforeInit(){\n\t\t\tlet noData = this.noData = this.which == null;\n\n\t\t\tthis._size = \"size-1\";\n\t\t\tthis.visible ??= true;\n\t\t\tthis.type ??= 'string';\n\t\t\tthis.value ??= this.data[this.which];\n\n\t\t\tif(this.value) this.checkSize();\n\t\t}\n\n\t\tv2m$value(now){\n\t\t\tthis.checkSize(true);\n\t\t\tif(this.whenChanged)\n\t\t\t\treturn this.whenChanged(now);\n\n\t\t\tif(!this.noData)\n\t\t\t\tthis.data[this.which] = now;\n\t\t}\n\n\t\tcheckSize(reset){\n\t\t\tclearTimeout(this._rechecking);\n\t\t\tthis._rechecking = setTimeout(async ()=>{\n\t\t\t\tlet $el = this.$el('input');\n\t\t\t\tawait $.afterRepaint();\n\n\t\t\t\tif(reset){\n\t\t\t\t\t$el.css('max-width', '30px');\n\t\t\t\t\t$el.css('width', '');\n\t\t\t\t\tawait $.afterRepaint();\n\t\t\t\t}\n\n\t\t\t\tlet el = $el[0];\n\n\t\t\t\tif(el.offsetWidth < el.scrollWidth){\n\t\t\t\t\tthis._size = 'size-2';\n\t\t\t\t\t$el.css('width', (el.scrollWidth+5)+'px');\n\t\t\t\t}\n\t\t\t\telse if(this._size !== 'size-1') {\n\t\t\t\t\tthis._size = 'size-1';\n\t\t\t\t}\n\n\t\t\t\tif(reset) $el.css('max-width', '');\n\t\t\t}, 700);\n\t\t}\n\n\t\tclick(ev){\n\t\t\tev.stopPropagation();\n\t\t}\n\t}\n}, ()=> {});\n\n\n## scss-global\nsf-space[blackprint]{\n\t.node comp-port-input{\n\t\tinput{\n\t\t\tdisplay: inline-block;\n\t\t\tmax-width: 30px;\n\t\t\tbackground: #000000a8;\n\t\t\tcolor: white;\n\t\t\tborder: 1px solid gray;\n\t\t\tborder-radius: 5px;\n\t\t}\n\n\t\t&.size-2 {\n\t\t\tdisplay: block;\n   \t\t\tmargin-bottom: 10px;\n\t\t\tinput{\n\t\t\t\tmax-width: 120px;\n\t\t\t}\n\t\t}\n\t}\n}","## html\n<comp-port-textarea style=\"display: {{ visible ? '' : 'none' }}\" class=\"{{ _size }}\">\n\t<textarea @pointerdown=\"click\" @pointerup=\"click\" sf-bind=\"value\"></textarea>\n</comp-port-textarea>\n\n\n## js-global\nBlackprint.space.component('comp-port-textarea', {\n\ttemplate: #this.path, // 'Blackprint/component/comp-port-textarea.sf'\n\textend: class extends sf.Model {\n\t\tasync beforeInit(){\n\t\t\tlet noData = this.noData = this.which == null;\n\n\t\t\tthis._size = \"size-1\";\n\t\t\tthis.visible ??= true;\n\t\t\tthis.value ??= this.data[this.which];\n\n\t\t\tif(this.value) this.checkSize(false, this.value);\n\t\t}\n\n\t\tv2m$value(now){\n\t\t\tthis.checkSize(true, now);\n\t\t\tif(this.whenChanged)\n\t\t\t\treturn this.whenChanged(now);\n\n\t\t\tif(!this.noData)\n\t\t\t\tthis.data[this.which] = now;\n\t\t}\n\n\t\tcheckSize(reset, now){\n\t\t\tclearTimeout(this._rechecking);\n\t\t\tthis._rechecking = setTimeout(async ()=>{\n\t\t\t\tlet $el = this.$el('textarea');\n\t\t\t\tawait $.afterRepaint();\n\n\t\t\t\tif(now.length < 6)\n\t\t\t\t\tthis._size = \"size-1\";\n\t\t\t\telse if(now.length >= 6){\n\t\t\t\t\tthis._size = \"size-2\";\n\t\t\t\t\tlet el = $el[0];\n\n\t\t\t\t\t// Skip if textarea was larger than our auto control\n\t\t\t\t\t// I mean, if user have change the size manually\n\t\t\t\t\tif(el.offsetWidth > 150 || el.offsetHeight > 60)\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t$el.attr('style', 'width:50px;height:15px');\n\n\t\t\t\t\tlet w = el.scrollWidth;\n\t\t\t\t\tlet h = el.scrollHeight;\n\t\t\t\t\t$el.attr('style', `width:${w < 140 ? w : 140}px;height:${h < 50 ? h : 50}px`);\n\t\t\t\t}\n\t\t\t}, 700);\n\t\t}\n\n\t\tclick(ev){\n\t\t\tev.stopPropagation();\n\t\t}\n\t}\n}, ()=> {});\n\n\n## scss-global\nsf-space[blackprint]{\n\t.node comp-port-textarea {\n\t\ttextarea {\n\t\t\tmax-width: 40px;\n\t\t\tmax-height: 15px;\n\t\t\tmargin-left: 0px;\n\t\t\tborder: 1px solid #55ff528c;\n    \t\tbox-shadow: 0 0 2px #55ff528c;\n\t\t\tborder-radius: 5px;\n\t\t\tpadding: 1px 2px;\n\t\t\tvertical-align: middle;\n\t\t\tresize: none;\n\t\t\twhite-space: pre;\n\t\t\t&::-webkit-scrollbar {\n\t\t\t\twidth: 4px;\n\t\t\t\theight: 4px;\n\t\t\t}\n\t\t}\n\n\t\t&.size-2 {\n\t\t\tdisplay: block;\n   \t\t\tmargin-bottom: 10px;\n\t\t\ttextarea{\n\t\t\t\tmax-width: unset;\n\t\t\t\tmax-height: unset;\n\t\t\t\tresize: both;\n\t\t\t}\n\t\t}\n\t}\n}","## comment, This will be used for sf-each for above element\n## html\n<drop-down class=\"bp-dropdown-menu {{ hidden }}\" style=\"\n    display: {{visible ? 'block' : 'none'}};\n    transform: translate({{ x | 0 }}px, {{ y | 0 }}px);\n  \">\n  <div class=\"first\" style=\"display: {{ !title && 'none' }}\">{{ title || '' }}</div>\n  <input>\n  <ul>\n    <li sf-each=\"x in options\" :class=\"{{ x.divider ? 'divider' : '' }} {{ x.disabled ? 'disabled' : '' }} {{ x.description ? 'has-desc' : '' }}\" title=\"{{ x.info || '' }}\">\n      {{@if x.title != null:\n      \t{[ <a> ]} // Begin\n\n      \t// Icon on the left\n      \tif(x.icon != null){\n      \t\tif(x.icon.includes('//'))\n      \t\t\t{[ <img class=\"dropdown-icon\" :src=\"{{x.icon}}\"> ]};\n      \t\telse\n      \t\t\t{[ <i class=\"dropdown-icon {{x.icon}}\"></i> ]};\n      \t}\n\n      \t// Always use { [ enclosed template ]} to avoid vulnerability\n      \t// like the text being parsed as HTML\n      \t{[ <div class=\"title\">{{ x.title }}</div> ]} // Content\n\n\t\tif(x.description != null)\n      \t\t{[ <div class=\"description\">{{ x.description }}</div> ]};\n\n      \t// Add icon if the has deep menu\n      \tif(x.deep != null)\n      \t\t{[ <i class=\"{{ root.icon.more }} has-deep\"></i> ]};\n\n      \t{[ </a> ]} // End\n      }}\n    </li>\n  </ul>\n</drop-down>\n\n## scss-global\nsf-space[blackprint]{\n\t.bp-dropdown-menu {\n\t\tz-index: 10000;\n\t\topacity: 0.9;\n\n\t\tmargin-top: 7px;\n\t\tbackground-color: rgba(255, 255, 255, 0.96);\n\t\tbox-shadow: 1px 1px 11px 3px black;\n\t\tborder: inherit;\n\t\tposition: fixed;\n\t\ttop: 0;\n\t\tleft: 0;\n\t\tpadding: 0;\n\t\tborder-radius: 3px;\n\t\tbackground: white;\n\n\t\t// transition: 0.3s ease-out;\n\t\t// transition-property: visibility, opacity;\n\t\t&.hidden{\n\t\t\tvisibility: hidden;\n\t\t\topacity: 0;\n\t\t}\n\t\tinput{\n\t\t\tdisplay: none;\n\t\t\toutline: none;\n\t\t\tborder: none;\n\t\t\tborder-bottom: 1px solid black;\n\t\t\twidth: calc(100% - 4px);\n\t\t\tfont-family: 'Nunito', sans-serif, \"Font Awesome 5 Free\";\n\t\t\t&::placeholder {\n\t\t\t\ttext-align: center;\n\t\t\t}\n\t\t}\n\t\tul{\n\t\t\toverflow-x: hidden;\n\t\t\toverflow-y: auto;\n\t\t\tmax-height: 300px;\n\t\t}\n\n\t\tli {\n\t\t\tposition: relative;\n\t\t\tvertical-align: baseline;\n\t\t\tdisplay: inherit !important;\n\t\t\tpadding: 8px 16px 8px 8px;\n\t\t\tmin-width: 110px;\n\t\t\tborder-bottom: 1px dashed darkgray;\n\t\t\tfont-size: 16px;\n\t\t\tmax-width: 400px;\n\t\t\tcursor: pointer;\n\t\t\tcolor: black;\n\n\t\t\t&.has-desc {\n\t\t\t\tpadding: 2px 16px 2px 8px;\n\n\t\t\t\ta{\n\t\t\t\t\tdisplay: block;\n\t\t\t\t}\n\t\t\t\t.title{\n\t\t\t\t\tfont-size: 14px;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t.description {\n\t\t\t\tfont-size: 12px;\n\t\t\t\tcolor: gray;\n\t\t\t\toverflow: hidden;\n\t\t\t\ttext-overflow: ellipsis;\n\t\t\t\twhite-space: nowrap;\n\t\t\t}\n\n\t\t\t> * {\n\t\t\t\tpointer-events: none;\n\t\t\t}\n\n\t\t\t&:hover{\n\t\t\t\tbackground: lightgray;\n\t\t\t}\n\n\t\t\tli > a > span {\n\t\t\t\tpadding-right: 6px;\n\t\t\t}\n\t\t}\n\t}\n\n\tul li .has-deep{\n\t\ttop: 11px;\n\t\tposition: absolute;\n\t\tright: 5px;\n\t}\n\n\tsf-m[name=\"dropdown\"].has-search > drop-down > input{\n\t\tdisplay: block;\n\t}\n\n\tdrop-down.bp-dropdown-menu drop-down{\n\t\topacity: 1;\n\t}\n\n\tdrop-down{\n\t\t&> .first {\n\t\t\tdisplay: block;\n\t\t\tpadding: 5px 10px;\n\t\t\ttext-align: center;\n\t\t\tfont-weight: bold;\n\t\t\tfont-size: 16px;\n\t\t\ttext-transform: capitalize;\n\t\t\tletter-spacing: 1px;\n\t\t\tcolor: white;\n\t\t\tbackground: #ba2f63;\n\t\t\tbox-shadow: 0 0 5px #d12867;\n\t\t}\n\t\tul{\n\t\t\tmargin: 0;\n\t\t\tpadding: 0;\n\n\t\t\tli a {\n\t\t\t\tdisplay: flex;\n\t\t\t\tdiv{\n\t\t\t\t\tpadding-left: 5px;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t.dropdown-icon {\n\t\t\t\tpadding-right: 5px;\n\t\t\t\tfloat: left;\n\t\t\t\talign-self: center;\n\t\t\t}\n\n\t\t\tli.disabled, li.disabled:hover{\n\t\t\t\tcursor: default !important;\n\t\t\t\tbackground: #888;\n\t\t\t}\n\t\t}\n\t}\n}\n\n## js-global\n// =====================================================================\n// ============== Model <sf-m name=\"dropdown\"></sf-m> ==================\n// =====================================================================\nBlackprint.space.model('dropdown', function(My){\n\tMy.menus = [];\n\tMy.onCancel = void 0;\n\tMy.className = '';\n\tMy.hasSearch = false;\n\tMy.searchActive = false;\n\tMy.pendingDeepOpen = false;\n\tMy.pendingDeepOpen_ = 0;\n\n\tMy.icon = {\n\t\tmore: 'fa fa-chevron-right'\n\t};\n\n\t// menus: [{title, callback}, {title, deep:[{...}]}, ...]\n\tMy.show = function(menus, { x, y, event, element, title, className, hasSearch, searchObject }){\n\t\tMy._event = event;\n\n\t\t// Remove last dropdown if haven't been closed\n\t\tif(My.menus.length !== 0)\n\t\t\tMy.menus.splice(0);\n\t\telse\n\t\t\taddBackdrop();\n\n\t\tmenus.title = title;\n\n\t\tif(element !== void 0){\n\t\t\tlet rect = element.getBoundingClientRect();\n\t\t\tmenus.x = rect.x + 5;\n\t\t\tmenus.y = rect.y + rect.height;\n\t\t}\n\t\telse if(x !== void 0){\n\t\t\tmenus.x = x;\n\t\t\tmenus.y = y;\n\t\t}\n\t\telse{\n\t\t\tmenus.x = event.x;\n\t\t\tmenus.y = event.y;\n\t\t}\n\n\t\tmenus.event = event;\n\t\tfor (var i = menus.length - 1; i >= 0; i--) {\n\t\t\tif(menus[i].hide)\n\t\t\t\tmenus.splice(i, 1);\n\t\t}\n\n\t\tMy.className = className || '';\n\t\tMy.menus.push(menus);\n\n\t\tif(hasSearch){\n\t\t\tlet el = My.$el('input').eq(0);\n\t\t\tlet debounce = 0;\n\t\t\tlet ref = My.menus[0];\n\t\t\tlet menuCopy = My.menus[0].slice(0);\n\t\t\tel.attr('placeholder', ' Type here to search...');\n\t\t\tMy.hasSearch = true;\n\n\t\t\tfunction onClick(ev){\n\t\t\t\tlet item = ev.target.model;\n\t\t\t\titem.callback.apply(item.context, item.args);\n\n\t\t\t\tMy.$el('drop-down > ul').off('click', onClick);\n\t\t\t\tMy.hide();\n\t\t\t}\n\n\t\t\tel.on('keyup', function(ev){\n\t\t\t\tclearTimeout(debounce);\n\t\t\t\tdebounce = setTimeout(()=> {\n\t\t\t\t\tlet value = el[0].value;\n\t\t\t\t\tif(!value || !My.hasSearch){\n\t\t\t\t\t\tMy.searchActive = false;\n\t\t\t\t\t\tel[0].value = '';\n\n\t\t\t\t\t\tref.splice(0);\n\t\t\t\t\t\tref.push(...menuCopy);\n\n\t\t\t\t\t\tMy.$el('drop-down > ul').off('click', onClick);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tMy.searchActive = true;\n\t\t\t\t\tlet checks = value.split(' ').map(v => {\n\t\t\t\t\t\tlet temp = RegExp(v, 'i');\n\t\t\t\t\t\ttemp.found = false;\n\t\t\t\t\t\treturn temp;\n\t\t\t\t\t});\n\n\t\t\t\t\tlet results = [];\n\t\t\t\t\tfunction deepFindFilter(list, docs, lastPath=''){\n\t\t\t\t\t\tfor(let i=0; i < list.length; i++){\n\t\t\t\t\t\t\tlet item = list[i];\n\t\t\t\t\t\t\tlet getDocs = docs?.[item.title];\n\t\t\t\t\t\t\tlet fullPath = lastPath + item.title+' > ';\n\n\t\t\t\t\t\t\tif(item.deep != null){\n\t\t\t\t\t\t\t\tdeepFindFilter(item.deep, getDocs, fullPath);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\tlet allFound = true;\n\t\t\t\t\t\t\t\tfor(var k=0; k < checks.length; k++){\n\t\t\t\t\t\t\t\t\tlet ref = checks[k];\n\t\t\t\t\t\t\t\t\tif(ref.test(fullPath)) ref.found = true;\n\t\t\t\t\t\t\t\t\telse allFound = false;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tlet description;\n\t\t\t\t\t\t\t\tif(getDocs != null){\n\t\t\t\t\t\t\t\t\t;({ description } = getDocs);\n\n\t\t\t\t\t\t\t\t\tif(allFound === false){\n\t\t\t\t\t\t\t\t\t\tfor(let k=0; k < checks.length; k++){\n\t\t\t\t\t\t\t\t\t\t\tlet ref = checks[k];\n\t\t\t\t\t\t\t\t\t\t\tif(ref.test(description)) ref.found = true;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Check and reset flag\n\t\t\t\t\t\t\t\tallFound = true;\n\t\t\t\t\t\t\t\tfor(let k=0; k < checks.length; k++){\n\t\t\t\t\t\t\t\t\tlet ref = checks[k];\n\t\t\t\t\t\t\t\t\tif(ref.found === false) allFound = false;\n\t\t\t\t\t\t\t\t\tref.found = false;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif(allFound === false) continue;\n\n\t\t\t\t\t\t\t\tresults.push(Object.assign({ description, info: description }, item, {title: fullPath.slice(0, -3)}));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tdeepFindFilter(menuCopy, searchObject);\n\n\t\t\t\t\tfor (var i = 0; i < My.menus.length; i++)\n\t\t\t\t\t\tMy.menus.getElement(i).model.deepRemove();\n\n\t\t\t\t\tref.splice(0);\n\t\t\t\t\tref.push(...results);\n\n\t\t\t\t\tMy.$el('drop-down > ul').on('click', onClick);\n\t\t\t\t}, 300);\n\t\t\t});\n\n\t\t\tsetTimeout(()=> el.focus(), 200);\n\t\t}\n\n\t\treturn My;\n\t}\n\n\tMy.hide = function(){\n\t\tfor (var i = 0; i < My.menus.length; i++)\n\t\t\tMy.menus.getElement(i).model.deepRemove();\n\n\t\tMy.pendingDeepOpen = false;\n\t\tMy.pendingDeepOpen_ = 0;\n\t\tMy.menus.splice(0);\n\t\tremoveBackdrop();\n\n\t\tMy.className = '';\n\t\tMy.hasSearch = false;\n\n\t\tMy.$el('input').off('keyup');\n\t}\n\n\tvar backdropCreated = false;\n\tfunction backdropListener(ev){\n\t\tif($(ev.target).parent('sf-m')[0] === sf.Window.source(My.$el, My._event))\n\t\t\treturn;\n\n\t\tremoveBackdrop();\n\n\t\tMy.hide();\n\t\tMy.onCancel && My.onCancel();\n\t}\n\n\tvar backdrop = $('<div class=\"ground-backdrop\"></div>');\n\tfunction addBackdrop(){\n\t\tif(backdropCreated) return;\n\n\t\tbackdrop.insertBefore(sf.Window.source(My.$el, My._event));\n\t\tsetTimeout(function(){\n\t\t\tbackdrop.addClass('show');\n\t\t\t$(sf.Window).on('pointerdown', backdropListener);\n\t\t\t$(sf.Window).once('contextmenu', ev => ev.preventDefault());\n\t\t\tbackdropCreated = true;\n\t\t}, 10);\n\t}\n\n\tfunction removeBackdrop(){\n\t\tbackdropCreated = false;\n\t\tbackdrop.removeClass('show');\n\n\t\tsetTimeout(()=> {\n\t\t\tbackdrop.remove();\n\t\t}, 200);\n\n\t\t$(sf.Window).off('pointerdown', backdropListener);\n\t}\n});\n\n// =====================================================================\n// ============== Component <drop-down></drop-down> ====================\n// =====================================================================\nBlackprint.space.component('drop-down', {template: #this.path}, function(My, include, $item){\n\tMy.visible = false;\n\tMy.hidden = 'hidden'; // We also need to hide it before repaint\n\n\tMy.options = $item;\n\tMy._parent = $item._parent;\n\tMy.x = $item.x;\n\tMy.y = $item.y;\n\tMy.root = include('dropdown');\n\tMy.width = 0;\n\tMy.height = 0;\n\tMy.disabled = $item.disabled === true;\n\n\tfor (var i = $item.length - 1; i >= 0; i--) {\n\t\tif($item[i].hide)\n\t\t\t$item.splice(i, 1);\n\t}\n\n\t// First dropdown title\n\tMy.title = $item.title;\n\n\tvar currentDeepLevel, $el;\n\tMy.init = function(){\n\t\tif($item.event !== void 0){\n\t\t\tvar el = sf.Window.source(My.$el, $item.event);\n\t\t\tif(el === null) return;\n\t\t\t$el = $(el);\n\t\t}\n\t\telse $el = My.$el;\n\n\t\tMy.visible = true;\n\n\t\t// Check position when the element rendered\n\t\tvar ulElem = sf.Window.source(My.$el, $item.event).querySelector('ul');\n\t\t$.afterRepaint().then(function(){\n\t\t\tlet x = 0, y = 0;\n\t\t\tlet parent = My._parent;\n\t\t\tlet w = parent !== void 0 ? parent.width : 0;\n\n\t\t\twhile(parent !== void 0){\n\t\t\t\tx += parent.x;\n\t\t\t\ty += parent.y;\n\t\t\t\tparent = parent._parent;\n\t\t\t}\n\n\t\t\tMy.width = ulElem.offsetWidth;\n\t\t\tMy.height = ulElem.offsetHeight;\n\n\t\t\tif(x + My.x + My.width > sf.Window.focus.innerWidth)\n\t\t\t\tMy.x -= My.width + w;\n\n\t\t\tif(y + My.y + My.height > sf.Window.focus.innerHeight)\n\t\t\t\tMy.y -= My.height;\n\n\t\t\tMy.hidden = '';\n\t\t});\n\n\t\t// Find nested options and add event listener on mouse hover\n\t\tvar options = My.options;\n\t\tfor (var i = 0; i < options.length; i++) {\n\t\t\tlet opt = options[i];\n\t\t\tconst elem = $(options.getElements(i));\n\n\t\t\tif(opt.deep !== void 0){\n\t\t\t\tfunction openDeep(ev){\n\t\t\t\t\tif(currentDeepLevel !== void 0)\n\t\t\t\t\t\tMy.deepRemove();\n\n\t\t\t\t\tif(opt.hover !== void 0)\n\t\t\t\t\t\topt.hover.apply(opt.context, opt.args);\n\n\t\t\t\t\tvar deep = opt.deep;\n\t\t\t\t\tdeep.event = ev;\n\t\t\t\t\tdeep._parent = My;\n\n\t\t\t\t\t// Use the cache instead\n\t\t\t\t\tif(deep.el !== void 0){\n\t\t\t\t\t\tcurrentDeepLevel = deep.el;\n\t\t\t\t\t\tdeep.el.model.y = deep.yi - (deep.ul?.scrollTop || 0);\n\t\t\t\t\t\t$el.append(deep.el);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tdeep.ul = My.$el.children('ul')[0];\n\n\t\t\t\t\t// Initialize position once\n\t\t\t\t\tdeep.x = ulElem.offsetWidth;\n\t\t\t\t\tdeep.yi = ev.target.offsetTop - 7;\n\t\t\t\t\tdeep.y = deep.yi - (deep.ul?.scrollTop || 0);\n\n\t\t\t\t\t// Create dropdown in current sf-space\n\t\t\t\t\tdeep.el = currentDeepLevel = new $DropDown(deep, My.$space);\n\t\t\t\t\tcurrentDeepLevel.sf$noGC = true; // Avoid framework's GC\n\t\t\t\t\t$el.append(currentDeepLevel);\n\t\t\t\t}\n\n\t\t\t\telem.on('mouseover', function(ev){\n\t\t\t\t\tMy.root.pendingDeepOpen = ev.target;\n\t\t\t\t\tclearTimeout(My.root.pendingDeepOpen_);\n\n\t\t\t\t\tMy.root.pendingDeepOpen_ = setTimeout(()=> {\n\t\t\t\t\t\tif(My.root.pendingDeepOpen === ev.target)\n\t\t\t\t\t\t\topenDeep(ev);\n\t\t\t\t\t}, 200);\n\t\t\t\t});\n\n\t\t\t\telem.on('click', openDeep);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\telem.on('mouseover', function(ev){\n\t\t\t\tMy.root.pendingDeepOpen = ev.target;\n\t\t\t\tclearTimeout(My.root.pendingDeepOpen_);\n\n\t\t\t\tMy.root.pendingDeepOpen_ = setTimeout(()=> {\n\t\t\t\t\tif(currentDeepLevel !== void 0){\n\t\t\t\t\t\tMy.deepRemove();\n\t\t\t\t\t\tcurrentDeepLevel = void 0;\n\t\t\t\t\t}\n\n\t\t\t\t\topt.hover && opt.hover.apply(opt.context, opt.args);\n\t\t\t\t}, 200);\n\t\t\t});\n\n\t\t\tif(opt.callback){\n\t\t\t\telem.on('click', function(ev){\n\t\t\t\t\tif(opt.unhover !== void 0)\n\t\t\t\t\t\topt.unhover.apply(opt.context, opt.args);\n\n\t\t\t\t\topt.callback.apply(opt.context, opt.args);\n\t\t\t\t\tMy.root.hide();\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif(opt.unhover){\n\t\t\t\telem.on('mouseout', function(ev){\n\t\t\t\t\topt.unhover.apply(opt.context, opt.args);\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tMy.deepRemove = function(){\n\t\tif(currentDeepLevel === void 0)\n\t\t\treturn;\n\n\t\tcurrentDeepLevel.remove();\n\t\tcurrentDeepLevel.model.deepRemove();\n\t}\n});","## scss-global\nsf-space[blackprint] .nodes {\n\tbpic-bp-env-get, bpic-bp-env-set,\n\tbpic-bp-var-get, bpic-bp-var-set,\n\tbpic-bp-fnvar-input, bpic-bp-fnvar-output {\n\t\t.content {\n\t\t\t.center{\n\t\t\t\ttext-align: center;\n\t\t\t\tbackground: #00f3ff4d;\n\t\t\t\tdisplay: inline-block;\n\t\t\t\tpadding: 4px 12px;\n\t\t\t\tborder-radius: 5px;\n\t\t\t\tfont-size: 15px;\n\n\t\t\t\t.description {\n\t\t\t\t\tfont-size: 12px;\n\t\t\t\t\tcolor: darkgray;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t.ports{\n\t\t\t\tmargin-top: 10px;\n\t\t\t}\n\n\t\t\t.ports > div.name {\n\t\t\t\tdisplay: none;\n\t\t\t}\n\t\t}\n\t}\n\tbpic-bp-fnvar-input, bpic-bp-fnvar-output {\n\t\t.content .center{\n\t\t\tbackground: #7935a5cc;\n\t\t}\n\t}\n\tbpic-bp-env-get, bpic-bp-var-get, bpic-bp-fnvar-input {\n\t\t.content .center {\n\t\t\tmargin-left: -25px;\n\t\t\tmargin-right: -15px;\n\t\t}\n\t}\n\tbpic-bp-env-set, bpic-bp-var-set, bpic-bp-fnvar-output {\n\t\t.content .center {\n\t\t\tmargin-left: -15px;\n\t\t\tmargin-right: -25px;\n\t\t}\n\t}\n}\n\n## js-global\nlet BPVar = {html: `<div class=\"node {{ type }}\" style=\"transform:translate({{ x }}px,{{ y }}px)\">\n\t<sf-template path=\"Blackprint/nodes/template/routes.sf\"></sf-template>\n\n\t<div class=\"content\">\n\t\t<div class=\"left-port\">\n\t\t\t<sf-template path=\"Blackprint/nodes/template/input-port.sf\"></sf-template>\n\t\t</div>\n\n\t\t<div class=\"center\"\n\t\t\t@contextmenu.stopAll.prevent=\"nodeMenu(event)\"\n\t\t\t@dragmove=\"moveNode(event)\"\n\t\t\t@pointerdown=\"swapZIndex(event)\"\n\t\t\t@pointerup=\"useType(true)\"\n\t\t\t@pointerover=\"nodeHovered(event)\"\n\t\t\t@pointerout=\"nodeUnhovered(event)\"\n\t\t>{{ title }} <div class=\"description\">{{ data._scopeName.slice(0, 1).toUpperCase() + data._scopeName.slice(1) }} Variable</div></div>\n\n\t\t<div class=\"right-port\">\n\t\t\t<sf-template path=\"Blackprint/nodes/template/output-port.sf\"></sf-template>\n\t\t</div>\n\t</div>\n\t<sf-template path=\"Blackprint/nodes/template/other.sf\"></sf-template>\n</div>`};\n\nlet BPEnv = {html: `<div class=\"node {{ type }}\" style=\"transform:translate({{ x }}px,{{ y }}px)\">\n\t<sf-template path=\"Blackprint/nodes/template/routes.sf\"></sf-template>\n\n\t<div class=\"content\">\n\t\t<div class=\"left-port\">\n\t\t\t<sf-template path=\"Blackprint/nodes/template/input-port.sf\"></sf-template>\n\t\t</div>\n\n\t\t<div class=\"center\"\n\t\t\t@contextmenu.stopAll.prevent=\"nodeMenu(event)\"\n\t\t\t@dragmove=\"moveNode(event)\"\n\t\t\t@pointerdown=\"swapZIndex(event)\"\n\t\t\t@pointerover=\"nodeHovered(event)\"\n\t\t\t@pointerout=\"nodeUnhovered(event)\"\n\t\t>{{ title }} <div class=\"description\">Environment</div></div>\n\n\t\t<div class=\"right-port\">\n\t\t\t<sf-template path=\"Blackprint/nodes/template/output-port.sf\"></sf-template>\n\t\t</div>\n\t</div>\n\t<sf-template path=\"Blackprint/nodes/template/other.sf\"></sf-template>\n</div>`};\n\nlet BPFnVar = {html: `<div class=\"node {{ type }}\" style=\"transform:translate({{ x }}px,{{ y }}px)\">\n\t<sf-template path=\"Blackprint/nodes/template/routes.sf\"></sf-template>\n\n\t<div class=\"content\">\n\t\t<div class=\"left-port\">\n\t\t\t<sf-template path=\"Blackprint/nodes/template/input-port.sf\"></sf-template>\n\t\t</div>\n\n\t\t<div class=\"center\"\n\t\t\t@contextmenu.stopAll.prevent=\"nodeMenu(event)\"\n\t\t\t@dragmove=\"moveNode(event)\"\n\t\t\t@pointerdown=\"swapZIndex(event)\"\n\t\t\t@pointerover=\"nodeHovered(event)\"\n\t\t\t@pointerout=\"nodeUnhovered(event)\"\n\t\t>{{ data.name }} <div class=\"description\">Function {{ type === 'bp-fnvar-input' ? 'Input' : 'Output' }}</div></div>\n\n\t\t<div class=\"right-port\">\n\t\t\t<sf-template path=\"Blackprint/nodes/template/output-port.sf\"></sf-template>\n\t\t</div>\n\t</div>\n\t<sf-template path=\"Blackprint/nodes/template/other.sf\"></sf-template>\n</div>`};\n\nlet BPFn = {html: `<div class=\"node {{ type }}\" style=\"transform:translate({{ x }}px,{{ y }}px)\">\n\t<sf-template path=\"Blackprint/nodes/template/routes.sf\"></sf-template>\n\n\t<div class=\"content\">\n\t\t<div class=\"header\"\n\t\t\t@dblclick=\"openFunction(event)\"\n\t\t\t@contextmenu.stopAll.prevent=\"nodeMenu(event)\"\n\t\t\t@dragmove=\"moveNode(event)\"\n\t\t\t@click=\"swapZIndex(event)\"\n\t\t\t@pointerover=\"nodeHovered(event)\"\n\t\t\t@pointerout=\"nodeUnhovered(event)\"\n\t\t>\n\t\t\t<div class=\"title\"><div class=\"icon\"></div><div class=\"text\">{{ title }}</div></div>\n\t\t\t<div class=\"description\">{{ description }}</div>\n\t\t\t<div class=\"extra\">\n\t\t\t\t<div class=\"item\" sf-each=\"x in $decoration.marks\" title=\"{{ x.title || '' }}\">\n\t\t\t\t\t<i class=\"{{ x.icon }}\"></i>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<div class=\"left-port\">\n\t\t\t<sf-template path=\"Blackprint/nodes/template/input-port.sf\"></sf-template>\n\t\t</div>\n\n\t\t<div class=\"right-port\">\n\t\t\t<sf-template path=\"Blackprint/nodes/template/output-port.sf\"></sf-template>\n\t\t</div>\n\t</div>\n\t<sf-template path=\"Blackprint/nodes/template/other.sf\"></sf-template>\n</div>`};\n\nlet BPFnInOut = {html: `<div class=\"node func-in-out {{ type }}\" style=\"transform:translate({{ x }}px,{{ y }}px)\">\n\t<sf-template path=\"Blackprint/nodes/template/routes.sf\"></sf-template>\n\n\t<div class=\"content\">\n\t\t<div class=\"header\"\n\t\t\t@contextmenu.stopAll.prevent=\"nodeMenu(event)\"\n\t\t\t@dragmove=\"moveNode(event)\"\n\t\t\t@pointerdown=\"swapZIndex(event)\"\n\t\t\t@pointerup=\"createPort(true)\"\n\t\t\t@pointerover=\"nodeHovered(event)\"\n\t\t\t@pointerout=\"nodeUnhovered(event)\"\n\t\t>\n\t\t\t<div class=\"title\"><div class=\"icon\"></div><div class=\"text\">{{ title }}</div></div>\n\t\t</div>\n\n\t\t<div class=\"left-port\">\n\t\t\t<sf-template path=\"Blackprint/nodes/template/input-port.sf\"></sf-template>\n\t\t</div>\n\n\t\t<div class=\"right-port\">\n\t\t\t<sf-template path=\"Blackprint/nodes/template/output-port.sf\"></sf-template>\n\t\t</div>\n\t</div>\n\t<sf-template path=\"Blackprint/nodes/template/other.sf\"></sf-template>\n</div>`};\n\nlet BPEvent = {\n\tkeepTemplate: true,\n\ttemplate: 'Blackprint/nodes/default.sf',\n};\n\n$(function(){\n\tBlackprint.Sketch.registerInterface('BPIC/BP/Var/Get', BPVar,\n\tclass extends Blackprint._iface['BPIC/BP/Var/Get'] {\n\t\tinit(){ sf.watch(this.data, 'name', ()=> { this.title = this.data.name }); }\n\t});\n\tBlackprint.Sketch.registerInterface('BPIC/BP/Var/Set', BPVar,\n\tclass extends Blackprint._iface['BPIC/BP/Var/Set'] {\n\t\tinit(){ sf.watch(this.data, 'name', ()=> { this.title = this.data.name }); }\n\t});\n\tBlackprint.Sketch.registerInterface('BPIC/BP/Env/Get', BPEnv,\n\tclass extends Blackprint._iface['BPIC/BP/Env/Get'] {\n\t\tinit(){ sf.watch(this.data, 'name', ()=> { this.title = this.data.name }); }\n\t});\n\tBlackprint.Sketch.registerInterface('BPIC/BP/Env/Set', BPEnv,\n\tclass extends Blackprint._iface['BPIC/BP/Env/Set'] {\n\t\tinit(){ sf.watch(this.data, 'name', ()=> { this.title = this.data.name }); }\n\t});\n\tBlackprint.Sketch.registerInterface('BPIC/BP/FnVar/Input', BPFnVar, Blackprint._iface['BPIC/BP/FnVar/Input']);\n\tBlackprint.Sketch.registerInterface('BPIC/BP/FnVar/Output', BPFnVar, Blackprint._iface['BPIC/BP/FnVar/Output']);\n\tBlackprint.Sketch.registerInterface('BPIC/BP/Fn/Input', BPFnInOut, Blackprint._iface['BPIC/BP/Fn/Input']);\n\tBlackprint.Sketch.registerInterface('BPIC/BP/Fn/Output', BPFnInOut, Blackprint._iface['BPIC/BP/Fn/Output']);\n\tBlackprint.Sketch.registerInterface('BPIC/BP/Event/Listen', BPEvent, Blackprint._iface['BPIC/BP/Event/Listen']);\n\tBlackprint.Sketch.registerInterface('BPIC/BP/Event/Emit', BPEvent, Blackprint._iface['BPIC/BP/Event/Emit']);\n\n\tBlackprint.Sketch.registerInterface('BPIC/BP/Fn/Main', BPFn,\n\tclass extends Blackprint._iface['BPIC/BP/Fn/Main'] {\n\t\topenFunction(event){\n\t\t\tthis.node.instance._emit(\"node.function.open\", {\n\t\t\t\tevent, iface: this, function: this.node.bpFunction\n\t\t\t});\n\t\t}\n\t});\n});","## html\n<sf-space blackprint>\n  <sf-m name=\"container\"\n    class=\"{{ _isImporting ? 'importing-nodes' : '' }}\"\n    @wheel=\"scaleContainer(event)\"\n    @touchstart.capture=\"checkTouch(event)\"\n    @pointerdown.capture=\"recheckOffset(event) || pointerDown(event)\"\n    @pointerup.capture=\"pointerUp(event)\"\n    style=\"\n      min-width: {{ size.w }}px;\n      min-height: {{ size.h }}px;\n      transform: translate3d({{ pos.x }}px, {{ pos.y }}px, 0px)\n                 scale({{ scale }})\"\n  >\n    <!-- Put the cables behind the nodes -->\n    <sf-m name=\"cables\" class=\"cables\">\n      <!-- Put empty space event here, because this element filling the empty space -->\n      <!-- recalculatePath: ./container/cables.js -->\n      <!-- list: ./container/nodes.js -->\n      <svg\n        @contextmenu.stop.prevent=\"container.nodeScope.menu(event)\"\n        @pointerover.capture=\"container.nodeScope.pointerOut(event)\"\n        @pointerdown=\"container.moveContainer(event)\"\n      >\n        <g sf-each=\"x in list\" class=\"\n          {{ x.typeName }}\n          {{ x.valid ? '' : 'invalid' }}\n          {{ x.connected ? 'connected' : ''}}\n          {{ x.disabled ? 'disabled' : ''}}\n          {{ x.hasBranch ? 'has-branch' : ''}}\n          {{ x.selected ? 'selected' : ''}}\n          {{ x._inactive ? 'inactive' : '' }}\n        \" @contextmenu.capture.prevent=\"x.cableMenu(event)\">\n          <path\n            @pointerdown.capture=\"x.cablePathClicked(event)\"\n            d=\"M {{ recalculatePath(x) || x.head1[0] + ' ' + x.head1[1] }}\n               C {{ x.linePath }},\n                 {{ recalculatePath(x) || x.head2[0] + ' ' + x.head2[1] }}\"\n          ></path>\n          <circle\n            @pointerdown.capture=\"x.cableHeadClicked(event)\"\n            transform=\"translate({{ x.head2[0] }}, {{ x.head2[1] }})\"\n          ></circle>\n        </g>\n      </svg>\n      <div class=\"glow-cable\"></div>\n    </sf-m>\n\n    <!-- Nodes goes here -->\n    <sf-m name=\"nodes\" class=\"nodes\" style=\"user-select:none;\">\n      <!-- Managed from ./nodes.js -->\n      <div sf-each=\"item in list\" class=\"{{ item._nodeSelected ? 'selected' : '' }} {{ item._inactive ? 'inactive' : '' }}\"\n        @pointerover.capture=\"pointerOver(event, item)\"\n        @pointerup=\"checkNodeClick(event)\">\n        {{@exec\n          /* Lowercase and replace \"/\" with dash:\n             \"BPIC/Node/IFace\" ==> \"bpic-node-iface\"\n          */\n          var name = item.interface.replace(/[\\/.,<>:\\[\\]{}+_=`~!@#$%^*(\\\\|)]/g, '-').toLowerCase();\n          var node = sf.component.roots[name];\n\n          if(node === void 0){\n            throw new Error(\"Node element with interface '\"+name+\"' (\"+item.interface+\") was not found\");\n            return null;\n          }\n\n          // Create element from Blackprint's namespace\n          Blackprint._reuseIFace = item; // used in: src\\constructor\\Interface.js\n          return new node(item, $space);\n        }}\n      </div>\n    </sf-m>\n\n    <div class=\"select {{ select.show ? '' : 'hide' }}\" style=\"\n      height: {{ select.h }}px;\n      width: {{ select.w }}px;\n      transform: translate3d({{ select.x }}px, {{ select.y }}px, 0px)\n                 scale({{ select.ix ? '-':'' }}1, {{ select.iy ? '-':'' }}1);\n    \"></div>\n  </sf-m>\n\n  <sf-m name=\"dropdown\">\n    <drop-down sf-each=\"val in menus\"></drop-down>\n  </sf-m>\n</sf-space>\n\n## scss-global\nsf-m { display: block; }\nsf-space[blackprint]{\n  position: absolute;\n\n  sf-m[name=container] {\n    > .select {\n      background: #529fff40;\n      outline: 1px solid #0095ff;\n      position: absolute;\n      backface-visibility: hidden;\n      top: 0;\n      left: 0;\n      display: block;\n      transform-origin: top left;\n\n      &.hide {\n        display: none;\n      }\n    }\n  }\n\n  &, .nodes, .cables{\n    height: 100%;\n    width: 100%;\n    display: block;\n  }\n\n  .description{\n    margin-top: 3px;\n    white-space: pre-line;\n  }\n\n  .node{\n    textarea, input{\n      background: rgba(0, 0, 0, 0.63);\n      color: white;\n      border: none;\n    }\n    textarea{\n      margin: 0px 5px 0px -10px;\n    }\n\n    select{\n      background: #232323;\n      color: white;\n      border: 1px solid #6d6d6d;\n    }\n\n    &.input{\n      textarea{\n        margin-left: 5px;\n        margin-right: -10px;\n      }\n    }\n  }\n\n  .nodes .node.bp-skeleton{\n    min-width: 200px;\n\n    .header .description {\n      max-width: 200px;\n      font-size: 14px;\n      font-style: normal;\n    }\n\n    .input{\n      padding-right: 5px;\n    }\n    .right-port {\n      margin-left: 5px;\n    }\n\n    .ports.ArrayOf > .port {\n      background: white;\n      &:before {\n        content: unset;\n      }\n    }\n  }\n\n  .BP-Hide{\n    display: none;\n  }\n\n  .BP-AllowResync {\n    color: yellow;\n  }\n\n  @mixin portType($type, $color) {\n    .cables > svg > g.#{$type} {\n      circle{fill: #{$color}}\n      path{stroke: #{$color}}\n    }\n\n    .nodes .node .ports.#{$type} {\n      & > .port {\n        background: #{$color};\n        // color: #{$color};\n      }\n\n      comp-port-input input {\n        border: 1px solid #{$color}8c;\n        box-shadow: 0 0 2px #{$color}8c;\n      }\n\n      comp-port-textarea textarea {\n        border: 1px solid #{$color}8c;\n        box-shadow: 0 0 2px #{$color}8c;\n      }\n\n      &.inactive {\n        color: grey;\n        & > .port {\n          background: transparent;\n          border: 2px solid #{$color};\n          width: 8px;\n          height: 8px;\n          box-shadow: 0 0 4px #{$color};\n        }\n      }\n    }\n  }\n\n  @include portType(\"Number\", #00bfff);\n  @include portType(\"Object\", #9370db);\n  @include portType(\"Boolean\", #ff5959);\n  @include portType(\"String\", #55ff52);\n  @include portType(\"BP-Union\", #ffffff);\n  @include portType(\"BP-Route\", #ffac7b);\n\n  // BP-Route\n    .nodes .node .ports.BP-Route > .port {\n        // border: 2px solid #ffac7b;\n        border-radius: 2px;\n        transform: rotate(45deg);\n        height: 8px;\n        width: 8px;\n    }\n  // BP-Route\n\n  // BP-StructOf\n  .nodes .node .ports {\n    &.BP-StructOf {\n      & > .port {\n          overflow: hidden;\n          &:after {\n            content: '';\n            background: #ffffff;\n            width: 100%;\n            height: 100%;\n            transform: translate(4px, -4px) rotate(45deg);\n            outline: 2px black dashed;\n          }\n      }\n      &.BP-Open {\n        display: none; // ToDo: remove me\n        margin: 10px 10px 0 0;\n        .port{\n          display: none;\n        }\n      }\n    }\n    &.BP-StructSplit.BP-Last {\n      margin-bottom: 10px;\n    }\n\n    &.disabled{\n      text-decoration: line-through;\n      color: #727272;\n    }\n  }\n  // BP-StructOf\n\n  .cables > svg > g.BP-Route path {\n    stroke-dasharray: 10px;\n    stroke: orange;\n    stroke-linecap: round;\n  }\n\n  .cables .inactive{\n    opacity: 0.4;\n  }\n\n  .glow-cable{\n    position: absolute;\n    top: 0;\n    left: 0;\n  }\n\n  .bp-dot-glow{\n    position: absolute;\n    width: 8px;\n    height: 8px;\n    border-radius: 5px;\n    box-shadow: 0 0 10px yellow;\n    transform: translate(-5px, -5px); // Hide it first on out of bound container\n    background: yellow;\n    visibility: hidden;\n    // &::after{\n    //   content: '🍒';\n    // }\n  }\n\n  .nodes .node .ports.ArrayOf > .port {\n    background: none;\n    font-family: \"Font Awesome 5 Free\";\n    font-weight: 900;\n    font-size: 12px;\n\n    &:before{\n      content: \"\\f00a\";\n      margin-top: -1px;\n      position: absolute;\n    }\n  }\n\n  sf-m[name=\"container\"]{\n    transform-origin: top left;\n    backface-visibility: hidden;\n    touch-action: pinch-zoom;\n  }\n\n  .nodes{\n    .node:before{\n      left: -1px;\n      z-index: -1;\n      content: '';\n      box-shadow: 0px 0px 20px white;\n      background: #ffffff12;\n      width: 100%;\n      border-radius: 6px;\n      border: 1px solid black;\n      height: 100%;\n      top: -1px;\n      position: absolute;\n      opacity: 0;\n      transition: opacity 0.3s ease-in;\n    }\n\n    .highlight .node:before{\n      opacity: 1;\n    }\n\n    .routes div {\n      transform: rotate(45deg);\n      background: #ffac7b;\n      width: 10px;\n      border-radius: 3px;\n      box-shadow: 0 0 3px 0 black;\n      height: 10px;\n      border: 1px solid black;\n      position: absolute;\n      top: -7px;\n      &.in { left: -7px; }\n      &.out { right: -7px; }\n      &.hide { opacity: 0; }\n      &.disable { display: none; }\n    }\n    .routes.show div{\n      z-index: 1;\n    }\n    .routes.show div.hide{\n      opacity: 1;\n    }\n\n    .routes.no-update div {\n      &.in { background: #727272; }\n    }\n    .routes.disabled div {\n      display: none;\n    }\n  }\n\n  .cables{\n    position: absolute;\n    > svg{\n      // Apply only on direct child of .cables\n      filter: drop-shadow(0 0 2px black);\n      backface-visibility: hidden;\n      height: 100%;\n      width: 100%;\n      transform: translateZ(0px);\n\n      path, circle{\n        transition: 0.1s ease-in;\n        transition-property: stroke, fill;\n      }\n\n      .connected circle{\n        display: none;\n      }\n\n      .has-branch circle{\n        display: block;\n      }\n\n      g.selected circle{\n        r: 8;\n        fill: white;\n      }\n\n      .disabled{\n        opacity: 0.4;\n      }\n\n      circle{\n        r: 5px;\n        fill: orange;\n      }\n\n      path{\n        stroke: orange;\n        stroke-width: 3;\n        fill: none;\n      }\n\n      .invalid{\n        circle{fill: red !important; opacity: 0.6;}\n        path{stroke: red !important; opacity: 0.6;}\n      }\n\n      g:hover{\n        circle{fill: white !important;}\n        path{stroke: white !important;}\n      }\n\n      .highlight{\n        path{\n          stroke: white;\n        }\n        circle{\n          fill: white;\n        }\n      }\n    }\n  }\n\n  .nodes{\n    position: unset;\n\n    .selected .node {\n      border: 1px solid white;\n      box-shadow: 0 0 5px white;\n    }\n\n    .inactive .node {\n      filter: saturate(0) opacity(0.7);\n      &:hover{\n        filter: none;\n      }\n    }\n\n    .node{\n      color: white;\n      font-family: Arial;\n      border-radius: 5px;\n      border: 1px solid black;\n      box-shadow: 0 0 5px black;\n      position: absolute;\n      background: rgba(0,0,0,0.7);\n      backface-visibility: hidden;\n      transform: translateZ(0px);\n\n      @mixin headerColor($type, $borderColor, $bgA, $bgB, $bgC) {\n        &.#{$type} .header{\n          box-shadow: inset 0 0 3px $borderColor;\n          background: linear-gradient(120deg, $bgA 0%, $bgB 80%, $bgC 100%);\n        }\n      }\n\n      @include headerColor('event', #a05f5f, rgba(226, 18, 18, 0.7), rgba(229, 41, 41, 0.2), rgba(229, 32, 32, 0.1));\n      @include headerColor('input', #75a05f, rgba(108, 232, 93, 0.7), rgba(103, 255, 108, 0.2), rgba(130, 226, 124, 0.1));\n      @include headerColor('func-in-out', #b030ff, #9600c7b3, #42006ab3, #8332dbb3);\n\n      .header{\n        display: block;\n        text-align: left;\n        padding: 3px 5px 2px 5px;\n        border-radius: 5px 5px 0 0;\n        box-shadow: inset 0 0 3px cadetblue;\n        background: linear-gradient(120deg, rgba(41,184,229,0.7) 0%, rgba(41,184,229,0.2) 80%, rgba(32,124,229,0.1) 100%);\n\n        /*linear-gradient(160deg, rgba(41,184,229,0.7) 0%, rgba(41,184,229,0.2) 54%, rgba(32,124,229,0.1) 80%, rgba(32,124,229,0.2) 100%)\n\n        -webkit-gradient(\n          linear, left top, right bottom, from(rgba(41,184,229,0.7)),\n          to(rgba(41,184,229,0.2)), color-stop(.8,rgba(32,124,229,0.1))\n        );*/\n\n        .description{\n          font-size: 12px;\n          color: darkgray;\n          padding-right: 5px;\n          font-style: italic;\n        }\n\n        .extra{\n          position: absolute;\n          top: -12px;\n          right: -10px;\n          .item{\n            background: black;\n            border-radius: 50px;\n            box-shadow: 0 0 11px white;\n            height: 20px;\n            width: 20px;\n            padding: 2px;\n            font-size: 12px;\n            text-align: center;\n            display: inline-block;\n            margin-left: 5px;\n\n            i{\n              line-height: 21px;\n            }\n\n            &.node-route {\n              font-size: 15px;\n              line-height: 20px;\n              margin-left: 10px;\n              box-shadow: 0 0 17px 5px #ff8d00e3;\n              background: #53340e;\n              outline: 2px solid #ff8d00;\n            }\n          }\n        }\n\n        &.small{\n            position: absolute;\n            height: calc(100% - 5px);\n            border-radius: 5px 0 0 5px;\n        }\n      }\n\n      .content{\n        display: inline;\n        width: 100%;\n\n        &.header-small{\n          margin-left: 32px;\n        }\n      }\n\n      .other {\n        position: absolute;\n        bottom: calc(100% - 15px);\n        display: grid;\n        left: -1px;\n        justify-items: center;\n        right: -1px;\n        z-index: -1;\n\n        .list{\n          display: grid;\n        }\n\n        .item {\n          display: inline-flex;\n          margin-top: 10px;\n\n          &.comment {\n            border-radius: 5px;\n            width: calc(100% - 12px);\n            background: #0000009e;\n            outline: 1px solid black;\n            box-shadow: 0 0 5px white;\n            padding: 5px;\n            bottom: 25px;\n            font-size: 14px;\n            position: relative;\n          }\n        }\n      }\n\n      .ports{\n        &.inactive {\n          color: grey;\n          & > .port {\n            background: transparent;\n            border: 2px solid white;\n            width: 8px;\n            height: 8px;\n            box-shadow: 0 0 4px white;\n          }\n        }\n        &.unused {\n          display: none;\n        }\n\n        .port{\n          z-index: 200;\n          background: white;\n          height: 10px;\n          width: 10px;\n          border-radius: 100px;\n          border: 1px solid black;\n          box-shadow: 0 0 5px black;\n\n          &.event{\n            border-radius: 2px;\n            transform: rotate(45deg) skew(10deg, 10deg);\n          }\n        }\n\n        &._Exec {\n          .port {\n            background: white;\n            clip-path: path('M 0 0 L 6 0 C 8 1 12 5 12 6 C 12 7 8 11 6 12 L 0 12 C 3 9 2 10 5 6 C 3 3 2 2 0 0');\n            width: 12px;\n            height: 12px;\n            border-radius: 0;\n\n            border: none;\n            box-shadow: none;\n          }\n        }\n\n        &.Trigger{\n          // height: 20px;\n          .name{\n            line-height: 20px;\n          }\n          .port{\n            background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAYAAADE6YVjAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuMTM0A1t6AAADUUlEQVRIS7WWXUhTYRjH3Waf2gdUEmYhgRUEIcIkcywmCHrRjS5Q8GZahA5CglHsrrvUlAkLvBh1I12UiGAwbzYU/EIvRpgiBc27BEHNLMdmPv3/Z2eb284+gnrgN97z/J/nffa+5z3POQUiEgemB0dBMSgBV8EtYFThmD5qjGGs/vAcWiQG0QJHwCmdTlcGqsA9XHeAxyod9KlaGWMBc7IWiv4kChQj+bJer68BNvAC12/h/0A4pk/VahjLHDVXlzp5DJoOFIIiJF1C8h2DwdAJPCaT6aPf7/+5t7d3QDimjxpjGMsc5J4EBs6VqQjFE6AECVVI7MAEr20229dIJIKYZKPP4XBIe3u7eDweGR4efoncC+AY0Nw2GsWz4BoKNANXdXX1UigUOkCApkGTlpYW6e7ulpGREfF6vc+Rz/tTCFmzSBEoxSpMKOAA3snJyRDErDY1NSWNjY3S29srMzMz+/Pz8+2Yh384bctoXEUFijQDt9Fo/AwhL2tqahK73S5jY2MSDAYja2trzZgrbcto50EleATe4599h5CXuVwusVqtyr1ZWVmRnZ2dXWCGlFbkIqgBT4B3dnY2DCEvm5ubk4aGBhkcHJRAICDb29sSDod/QKoESUVKgQk8A7719fXfEPIyxEpdXZ309fXJ4uKibG1tKacP9g3cAPEiPOdm4AR+RvyNWSwW6enpkYWFBdnc3ORKVEUC4L8WSVtJ0nZtbGxkfD5SDbFp25XpnvyzG48iu1jNXUjxAoSWdIQHBgbyPsJutzt+hJeXl/dXV1fvYw4DpLQihx/GV2az+QuEvKy1tVW6urpkdHR0f3x8vBPzsFFqPoypbWVieno6Z1tBK1G2im1laGioH3PEmqRmW1EaJIpcRwGlQdbW1n7K1SDb2tqUBul0Ot8gtwJzKA0SaBZJbfUP1FYfzNTqqTGGscxBbs5Wn/GlVV9fv+Tz+X7FXloc00eNMYxlDnKzv7SUn8Trl+/3K0jm/XkI+nH9Dv4JwjF9qmZiLHPUXM0CJDGIFuLXxxkkl4PbwIprO3iqYqdP1coZC3J+sSQG0W3jko8DHmt+jdwEfFAtKhzTR40xjM24TTEU03DGto8H4jQ4B/itRTimjxpjsq5CRAr+AGaARw6hXaKlAAAAAElFTkSuQmCC);\n            background-size: 20px;\n            width: 20px;\n            height: 20px;\n\n            border: none;\n            box-shadow: none;\n          }\n        }\n      }\n\n      .output, .input{\n        margin-top: 1px;\n\n        // > = direct child\n        .ports > div {\n          display: inline-flex;\n        }\n        .ports > .name {\n          margin: 0 3px 0 5px;\n        }\n      }\n\n      .left-port{\n        position: relative;\n        float: left;\n      }\n      .right-port{\n        position: relative;\n        float: right;\n        text-align: right;\n        margin-left: 20px;\n      }\n\n      .output{\n        margin-right: 5px;\n        .name{\n          text-align: right;\n        }\n\n        .Trigger .port{\n          float: right;\n          margin-left: -1px;\n          margin-right: -5px;\n        }\n      }\n\n      .input{\n        padding-right: 20px;\n        margin-left: 5px;\n        white-space: nowrap;\n\n        .Trigger .port{\n          float: left;\n          margin-left: -2px;\n        }\n\n        input::-webkit-outer-spin-button,\n        input::-webkit-inner-spin-button {\n          -webkit-appearance: none;\n          margin: 0;\n        }\n\n        /* Firefox */\n        input[type=number] {\n          -moz-appearance: textfield;\n        }\n      }\n\n      .property{\n        display: flex;\n        justify-content: center;\n        margin-top: 5px;\n        margin-bottom: 5px;\n        .ports{\n          margin-right: 8px;\n          margin-left: 8px;\n          .port{\n            margin: 0 auto;\n          }\n        }\n      }\n    }\n  }\n}\n\nbody.blackprint-no-vfx sf-space[blackprint], body sf-space[blackprint] .importing-nodes {\n  .cables > svg{\n    filter: none;\n  }\n  .nodes .node{\n    transition: none;\n  }\n  .nodes * {\n    box-shadow: none !important;\n  }\n}\n\nbody sf-space[blackprint] .importing-nodes{\n  pointer-events: none;\n}"]}