@bluerobotics/bluevue 0.1.0

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.
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="400" height="400" viewBox="0 0 400 400"><g fill="#fff" fill-rule="evenodd"><path d="M185.5.4c0 .2-1 .3-2 .2a7 7 0 0 0-2.4.1q-.3.4-1.3.2c-.5 0-1.3 0-1.6.4q-.7.5-.3 0 .1-.5-.1-.5-.5 0-.5.4-.1.3-1.4.2-1.5-.3-2.5.5l-1 .8 1 .3q1.4.2.2.6-1 .3.1.3.8 0 1.1.5t-.2.1q-.5-.1.1.3t.7 1q0 .3 1.5 1.6 1.3 1.2.9 1-.6-.3 0 .5.3.8.7.9t.4.6.8.5.7.3c-.1.6.5 1.7.9 1.5q.3-.1.3.2.1.4.7 1.1.7.6.1.3-.4-.2 1 1.1t1 1.2q-.5-.3-.3.1t1 .5q.5 0 .3.2c-.3.4.9 2.5 1.5 2.5q.5 0 1.2.9l.8.9-1-.8q-1-.9-.7-.2.2.6 1 1l1.4 1q.4.4-.3 0-1-1-.3.2.5.9 1 1t1.2.8.2.4q-.7-.6-.6.1 0 .8 1 .6.4 0 .3.5 0 .4.4.5l.7.1-.2.6q-.7.9.9.7.3 0 0 .3 0 .3.3.4.6 0 0 .3t.4.8q1 .6.5 0t.3 0q.6.5.5.9t.7 1.3.6 1 .6.7q.9.7 1 1.3t.5 1q.4.2.1-.3-.2-.5.1-.2.5.3.5.8t.9 1.2q.7.5.3.4-.4-.2.5.7 1.1 1 1.3 1.7t1 1.5.8 1.3q0 .4.6 1 .9.6.3.6t.3.5q.7.5.8 1c0 1 .2 1.2 1 1.5q.6.2.5.5-.2.4.4.7.6.4.6.6c0 1 .9 2.7 1.2 2.2q.3-.6.4 0c.1 1.5 1 3.1 1.9 3.6q.8.4.6 1-.1.5.5 1.2.7.5.6 1.1-.1.5.7 1.1.7.5.6 1.2-.2.5.6.8 1 .1.3.8t.2.6q.5 0 .4.4-.2.3.1.4c.3 0 1 2.1 1 2.8q-.1.3.5.3t.4.3.4.6.1.9.3.5.2.4q-.7.2.3 1 1 .6.4.6t.3.7c.5.3 1 1.2 1 1.8.2 1.5.9 3.2 1.4 3.5q.5.3 0 1-.8.7.2.3.7-.3.4.5-.1.7.2.8.3 0 .4.7 0 .8.5 1.2.6.6 0 .3t-.5 0q0 .4.6.7t.4 1c-.2 1 .1 2 .6 1.7q.2 0 0 .6 0 .8.3.8t.2.6.2.6.2.6.4.6 1.2.6.6.1.6 0 1.1.3q.6-.1.6.1.1.3.8.2t.8.2.6.2q.6-.2.6.4 0 .5.6.6c.8 0 .8 0 2 .6q1 .5 1.4.2.5-.3 1.2 0 1.2.5 0 .2h-1c0 .5 1.8.8 2.1.4q.3-.5.3.3t.9.6q2-.2 1.6.4c-.3.5 1.7 1.3 2.6 1q.8-.2.5.3-.2.7.6.5.7-.1 1 .4.3.7 1 .4.8 0 .5.2-.1.4.3.3t1.2.5q.6.7 1.4.8.9 0 1 .4 0 .2.5.4t.3-.2c-.3-.6 1.1.5 1.6 1.2q.3.3.8.2t.8.3q.3.5-.1.2t-.5 0 .8.7q.7 0 .6-.2-.2-.3.4-.1.5.3.4.5c-.2.3.5.8 1 .7q.4 0 .8.6t1.1.7q.7 0 .8.4 0 .3.6.4.5 0 1 .8.4.7.7.5t.4.2.4.2q.4 0 .6.3.3.4-.1.2t-.5 0c0 .5 1.5 1.1 2 1q.4 0 .2.2c-.2.3.6 1 1.4 1l.6.4q.2.4-.2 0-.5 0-.5.2 0 .4.6.4t.8.6.9.8.2-.3q-.2-.4.4.2.5.7.6.4l.7 1c.5 1.1 1.8 2 2.6 1.7q.3 0 .1.2a39 39 0 0 0 8 7.7c-.2.7.4 1.8.8 1.6q.3-.2 0 .4-.2.9.5.4.8-.3.3.3-.7.8 1.2 1.2c.3 0 .9.6.9 1q.1.4 1.1 1.4 1.1.9.5.6-.7-.6-.6 0 0 .4 1 .8.9.3 1 .6h-.5q-.3-.2-.4.1.1.3 1.1 1 1 .4 1 1t1 1.9 1 1.4q-.2.2.4.4.5.3.4.6-.2.4.4.6.5.2.4.6t.3.6q.6.3.6.7.3 1.7 1.1 1.8.6 0 .4.6t.4 1q.6.2.3.3t.6 1q1 1 .5.8t-.3.4q.4.5.7.6.4 0-.1.4-.7.4 0 .3.7 0 .7.3c-.2.5 1 2.9 1.3 2.9q.3 0 .3.3-.2 1.3.4 1 .4 0 .4.2t-.4.4q-.4.1.5.8t.4.8q-.6 0 0 .8.4.6.8.5.3-.2.2.4-.2.5 0 .6.4 0 .2.7t.1.4c.5-.3 1 .9.8 2.3q-.2.9.3 1t.8.6q.4.8-.5 0-.4-.3.3.6c.8 1 .9 1.2.4 1.5q-.7.4.2.4.7 0 .4.6-.1.6.4 1.4t.3 1.4.2.3.3.6.3 1.2 0 .3-.3.6q.2.8.6.1.4-.4.1.7t.2.8.2.8.2.7.3.6.2 1.7q.5.9 0 1-.3.1-.2.7.2.8.6 0 .4-.4.1.7-.1 1 .2 1.6.5.5.2.6t.3.6q.6.8 0 .4t-.3.2.3 1.6.3.9.4.2-.5.4q-.6 0 0 .3.4.4.3 1.1l.1 1q.3 0 .3 1.8l.1 2.2q.6 1.2 0 2.1-.6.7 0 .3.6-.5-.1 3.2-.1.9.2.6c.5-.2.3 4.5-.2 6.4l.1.9c.5 0 .5 1.7 0 2q-.5.3 0 .3c.3 0 .4 1.1 0 1.8q-.2.5-.1 2.2 0 2-.6 1.9-.5 0-.2.3c.4.3.7 2.8.2 2.7q-.6-.1-.2 1 .2.7-.3 1.3-.6.9.1.4t.1.1q-.3.6-.2 1 0 .6-.2.6-.4.1-.6.8t.2.5 0 .6l-.5 1.6q0 .7-.4.8-.4 0 0 .6.6.5-.2 1.2-.6.8-.2.9t.4.5-.4.1-.1.8-.3.8-.2.3v.7q-.4 0-.2 1 .2 1.2-.3.7-.6-.3-.3.3.1.8-.5 2-.6 1.3-.3 1.2.5-.2 0 .3l-.4 1q0 .6-.5 1-.4.2-.2.6.1.5-.2.5t-.2.5-.1.6q-.4 0-.6.7l-.3 1.3q.4-.6.4-.1t-.7.9-.6.8-.3.3 0 .4q.8.4.1.4-.4 0-.3.6t-.1.6q-.4 0-.2.4.1.3-.3.8t-.4 1.1v.3c-.5-.3-1.6 1.2-1.3 1.7q.2.3-.1.4-.5 0-.2.4 0 .3-.2.4-.4 0-.3.3.2.4-.3.6t-.6.6.5.2q.4-.1-.2.3-.6.6-.7 1.3 0 .5-.4.4-.6-.2-.4 1 0 .5-.6 1.2-.6.9-.6.3 0-.4-.4.4c-.5 1-.6 1.4-.7 2.3q0 .5-.3.3c-.3-.3-1.4.8-1.1 1.3q.2.3-.4.6-.5.1-.4.6.3.3-.4.4-.5 0-.5.5.2.4-.4 1-.8.8 0 .3.4-.3-.5.6-1 1-.8 1.2.1.3-.3.3-.3 0-.2.3 0 .4-.5.9-.8.8-.3 0t-.3 0q-.8.4-.2.8.6.3-.1.3c-.6 0-1.3 1-1.2 1.7q0 .2-.5.3a1 1 0 0 0-.8.4q-.3.5.2.2t-.3.5q-.7.6-.6 1 .1.2-.3.2c-.8 0-2.8 2.3-2.5 2.8q0 .3-.9.9c-1 .5-5.7 5-5.3 5l-.3.7q-.4.7-1 .5-.4 0-.7.6-.4.8-.7.7-.4 0-1 1-.4.8-.5.6t-.8.6-.5.4-.4-.3q-.5.3-.3.9t-.3.3c-.4-.3-1.6.6-1.6 1.3q0 .3-.5.2a1 1 0 0 0-.9.3q-.3.4.3.1t0 .3-.9.5-.3.2-.3.3-1.2.8q-.8 1-.6.4.5-.7-.3 0-.5.6-1.2.8-.6.1-1.3 1-.6.7-.8.7c-.4-.2-1.3.4-1.1.7s-1.2 1-2.6 1.1q-.3 0-.2.4c.3.5-1 1-2.5 1.2q-.3 0-.2.5.2.5-.3.2-.7-.3-1 .5-.5.7-1 .5-.7-.2-.7.3 0 .3-.3.2-.4-.2-.4.2 0 .3-.4.2-.3-.2-.4.2 0 .4-.4.1-.3 0-.4.2 0 .4-.3.4-1.3-.2-1 .5.1.3-.3.2-.6-.1-1 .4-.6.4-1 .3-.2-.1-.3.2t-.6.1q-.5 0-.6.3t-.3.2c-.4-.2-.4 3.3 0 3.9q.2.5 0 1.6 0 1.3.4 1.3.3 0 .1 1.2t.2 1.2.2 1 .2 1 .1.5q0 .6.3 1.2.5.6 0 .6-.3 0 .3 1l.6 1.2v.4l-.1 1q0 .7.3.5.6-.3.2.7-.2 1 .3 1t0 .4q-.7.4 0 .4c.8 0 1 1 .2 1.3q-.3.2.2.2.7 0 .5.7t.1.4.2.6.4.5 0 .3q-.8 1 .4.7.7.2-.2 1.1-.6.7.3.3t.2.3q-.6.9.4.7.3 0 .1.7t.2.8q.2 0 .4.9 0 .7.4 1 .3.1.2.7-.3.6.2.4.3-.2.4 0 0 .5-.4.6-.2.1.4 1 .9.8.3 1.2-.5.4.2.4c.7 0 1.3 1.2.6 1.2q-.4 0 .2.5.8.6.2 1-.6.6.3.2.7-.3.5.2c-.4.6 0 1.7.6 1.4q.4-.2 0 .2 0 .5.3.9.7.3 0 .3-.8 0 0 .5c.7.5.8.7.8 1.7q0 .5.4.3t.2.1c-.3.6.1 1.8.6 1.5.3-.2.5.6.4 1.5q0 .2.3.3t.2.5.4.8.4.8q0 .5.2.6t.4.8q0 .7.4.8.3 0 .2.4-.2.3.1.3t.2.6.3 1q.5.6.5 1.2c0 .7.7 1.5 1 1.3s.8 1 .6 1.4q-.2.3.2.4.3 0 .2.4-.2.4.1.4.5.1 1.3 1.6.6 1.5.4 1.3-.5-.2-.2.4.3.5.5.4.3-.2.6.4.1.5-.2.4-.4-.2-.1.3.2.6.6.7t0 .3q-.9.5 0 .4.6 0 .5.4t.5 1.1q.8.9.6 1-.2.3.2.3t.3.3.6 1q.6.8.5 1.4-.2.8.6 1.2.6.5.5 1t.1.4q.5 0 1 .6.5.8 0 .5c-.7-.4.2 1.3 1.3 2.5q.6.7.4.8-.2 0 .4.6.8.6.3.4c-.7-.4-.6.4.3 1.5.8 1 2 1.5 1.4.7q-.1-.3.7-.2.9 0 1.4-.6.6-.6 1-.5.6 0 .6-.3t.4-.2.4-.1q0-.4.6-.6t.3.1q0 .3 1.2-.2t1.1-1q0-.3.2-.4.4.1.6.5t.2-.3q0-.9.4-.1.4.7 1.1-.2 1-1.2 0-.2-1.1.8-.3-.1.5-.6.9-.5c.4.3 2.7-1 2.7-1.4q0-.3.3-.2.4.1.4-.1 0-.5.6-.2.6 0 1.7-.9 1.3-1 1.3-.5t.3-.3 1.4-.7.8-.4q-.2-.6.5-.3.6.1.3-.2-.2-.8 1.9-1 .7-.2 1.3-.9.5-.7 1-.8c1 0 1.8-.6 1.6-1q-.2-.4.4-.2t.9-.3q.1-.5.5-.4.3.2.5-.4.4-.6 1-.5.9.3 1-.5.3-.7.5-.6c.3.4 1.7-.5 1.5-1q-.2-.2.3 0 .7 0 1.2-.8.8-1 1.2-.8.6 0 1.1-.7.7-.9.7-.3 0 .5.5-.4c.5-1 2.5-2.5 2-1.6q-.1.4.8-.6t1.4-1 .4-.4.3-.2q.4.3.4-.4t.6-.4 1-.6q.3-.8.4-.5 0 .3.6-.5.6-1 1.2-.5t.3-.1.4-.7q.5 0 .6-.6t.4-.4q.5.2 1.7-1l1.7-1.4q.3-.2.2-.6t.5.1q.7.8.5 0 0-.5.5-.4t.3-.2.7-1 1-1.3q0-.5.2-.5.4 0 1.5-1 1.3-1.4.4-.3-.4.7 2-1.7c1.4-1.5 2.8-2.7 3-2.7l.4-.6c.3-.8 3.5-4 4.1-4q.4 0 .4-.2a16 16 0 0 1 2.6-3q2.4-2.4 1.7-2-1 .8.2-.4 1.2-1 1.1-1.5 0-.2.5-.3c.7 0 3-2.9 2.6-3.3q-.1-.2.1-.1.4 0 .5-.2l1.5-1.6q1.3-1.4 1.1-1.8-.1-.3.4-.4.6 0 .6-.6t.7-.4.4 0q-.2-.4.2-.9.6-.7-.1-.3-.4.2.2-.3t.4-.6q-.3 0 .5-.4t.6-1 .4-.6q.7 0 .4-.4 0-.3.2-.4.4 0 .3-.3.1-.5 1.1-1.4 1-1 .6-.8-.5.3.2-.7.6-.8 1.2-1.2.6-.2.4-.5t.6-.8.6-1.1.8-1.2.7-1.2q-.1-.5.2-.3.3 0 .8-.6.3-.7 0-.8-.2 0 .4-.4t.7-1.2q0-.7 1-1.6.6-.9.7-1.4-.1-.4.2-.3c.4.2 1-.7 1-1.6q.1-.5.8-1t.8-1.3c.1-1.1.7-2.1 1-2 .4.3 1.3-1.6 1-2q-.2-.5.5-.8.5-.4.3-.4-.2-.1.7-1.3 1-1.1.9-1.7-.2-.5.2-.6.3 0 .1-.4-.1-.3.2-.3.4-.2 1.2-1.6.8-1.6.3-1.3-.4.1.2-.5l.4-1q-.2-.3.2-.3.3 0 .2-.7-.2-.6.1-.4.4 0 1-1.1.6-1.3.3-1.2t-.1-.3.6-.6q.3 0 .1-.4-.1-.3.2-.4.5 0 .2-.6l.1-.6q.4-.1 1-1.4t.3-1.2q-.3.3-.2-.5.3-.7.7-.5t.1-.4q-.2-.7.4-1.2.5-.6.4-1-.2-.4.3-.8t.4-1.3.2-.5q.6.4.3-.3t.1-.6q.4-.1.4-1t.4-1 .2-.6.2-.6q.5 0 .2-.8 0-.6.3-.5.3.3.1-.6 0-.7.2-.6.5.3.2-.5-.1-.9.2-.6.4.2.1-.7t.2-.6.4-.2c-.2-1.1.5-3.9.9-3.6q.4.3.2-.4-.2-.5 0-.6.4-.1.3-.8t.2-.8.2-.6.2-.8q.2-.1.2-1-.1-.8.2-.5.5.3.2-.8t.2-.8.2-.8.2-.7.2-.8.2-.8q.4.3.2-.2t.1-1 .2-1.2q0-.7.2-1c.3 0 .5-1 .5-1.8q0-1.6.4-1.7.2 0 0-1 0-.9.3-1 .4 0 .3-1.3 0-1.2.2-1.6.2-.2 0-.8-.1-.5.2-.5.4-.1.4-1.3.1-3.7.5-4 .3-.3 0-1.2 0-1 .3-1.5.5-.5.3-2-.1-1.2.2-1.3.3 0 .3-.4t-.5-.2 0-.2.2-1.8q0-1.3.3-1.3t.2-2.4q0-2.1.2-2.3c.1 0 .3-6.2.3-13.7a170 170 0 0 0-1.2-21.5q-.5-.6 0-.2.5.1.5-.2t-.4-.4q-.3 0-.1-1.6.3-1.5-.2-1.4-.3.3-.3-1.3.1-1.4-.2-1.7-.2-.3-.2-1.4.1-1-.2-1.4-.3-.2 0-1.3 0-1.2-.3-1.2-.4 0-.3-.5t-.3-1q-.5-.7.1-.3t.3-.6l-.4-1.4q0-.5-.3-.5t-.1-1q0-1-.3-.7-.4.3-.2-.7t0-1.3-.2-1-.2-1q-.3-.1-.2-1 .1-.7-.2-.7t-.2-.9q.3-.8-.3-.5t-.2-.7q.3-1.2-.2-.8t-.2-.8q.3-1-.1-.8-.5.3-.2-.8t-.2-.8c-.4.3-.6-1-.5-2.4q0-.5-.2-.5t-.4-1.2q0-1.2-.5-1.5t-.5-1.5-.3-1.3-.1-.6-.3-.3-.2-.2c.3-.5-.1-2.4-.6-2.2q-.2 0 0-.6 0-.9-.2-.6-.5.2-.2-.6.1-.8-.2-.6t-.3-.5q.2-.8-.2-.8t-.3-.3q.1-.1-.2-.7a4 4 0 0 1-.6-1.8q-.1-1-.7-1.8-.5-.6-.4-1.1t-.2-.3q-.5.3-.2-.4 0-.5-.2-.6t-.2-.6q.1-.6-.1-.4-.3 0-.6-.6 0-.7.2-.6.9.6-.4-1-.7-.7-.6-1.3.2-.5-.4-.7-.6-.3-.6-.8c.2-1 0-1.9-.4-1.6q-.3.1-.2-.4.3-.5-.4-.8-.6-.2-.4-.8.1-.5-.1-.6c-.3 0-.8-1-1-2.1s-.7-2.2-1-2q-.4.3-.1-.4.2-.7-.3-.4t-.3 0c.3-.5-1.3-4.1-2.2-4.8q-.5-.5-.4-.8t-.5-.6-.4-.8-1-2q-1-1.2-1-1.6.2-1.2-.7-1.3-.6 0-.4-.6t-.4-.9-.9-2q0-.4-.6-.4t-.3-.4q.2-.5-.4-1l-.7-.7q-.3-1.6-.8-1.1-.5.2-.2-.4.1-.6-.2-.6-.5 0-.5-.6t-.3-.4q-.2 0-.3-.6 0-.8-.4-.6-.4 0-.4-.6t-.5-.7q-.4 0-.5-.6c0-.4-.6-1.4-1.3-2.1a7 7 0 0 1-1.5-2q0-.7-.6-1-.6-.5-.5-.7 0-.3-1.2-1.7l-1.3-1.7q0-.2-.7-.5t-.3-.3-.4-.7-.2-.3q.5.1-.7-1-1.3-1.1-.9-1 .6.3.3-.1t-.9-.5-.3-.3c.3-.5-1-2-1.6-2q-.5 0-.4-.4.2-.2-.4-.5-.5-.3-.4-.7 0-.5-.8-1t-.7-.6q.2-.4-.6-.7-.7-.5-.6-.7c.3-.3-1.4-2-2-2l-.7-.5q-.3-.4.2-.1.3 0-1.9-2t-2.2-2.5c.2-.4-1.6-2-1.9-1.8 0 .2-1.2-.9-2.4-2.2q-2-2.2-2-2 .3.6-.1.3l-.5-.7q0-.6-1-1.4t-1-.6-.5-.5-1-.7-.4-.3-.6-1.1q-1-.8-.2.2.4.7-.7-.6t-1.6-1.2q-.4 0-.2-.3.1-.4-.7-.8l-1.4-1.1q-.5-.7-.2 0 .1.4-1-.9-1.1-1.1-1-.7l-1.3-1.1q-1.6-1.6-2.1-1.4-.5.1-.2 0c.4-.5-2.4-2.6-3.3-2.6q-.7-.1-1.2-.8t-1.7-1.6q-1.3-1-.5-.2.9 1.2-.5 0-1-.7-.8-1 0-.3-.5-.3t-.6-.4q0-.4-.3-.2-.4.1-.6-.4-.3-.5-1-.6-.8 0-.6-.4t-.2-.2-1.6-1q-1-1-1.5-1-1.2 0-1-.5t-.2-.4l-.8-.2-.8-.1q-.3-.1-.2-.5.2-.3-.1-.4l-.8-.2-.8-.1q-.5 0-.2-.4 0-.3-.8-.8-1-.5-.8 0 .3.3-.5 0-.7-.6-.6-.9.1-.5-1.1-.3-.3 0-.3-.3 0-.4-.6-.6-.6-.3-.4.2t-.9-.6q-1.1-1-1.7-.8-.4.2-.2-.1c.2-.4-2-1.6-2.6-1.4q-.2 0-.3-.3 0-.4-.3-.2-.4.1-.4-.2t-.3-.3q-.2.2-.8-.3t-1.2-.4-.2-.2-.4-.2q-.6 0-.7-.2t-.3-.2q-.4.3-.4-.1-.1-.4-1-.4t-1.2-.6-.6-.4q-.3.1-.4-.2 0-.4-.4-.3-.6 0-1.6-.6t-1.5-.5q-.5.4-.2-.2.4-.5-.5-.2t-1.1-.3c-.5-.7-4.3-2.2-5-2q-.7.3-.5-.1.2-.3-.3-.7-.6-.2-.3.3.1.4-.5-.2-.8-.7-1.5-.4-.9.3-.4-.3.3-.5-.6-.3t-.5-.2q.2-.3-.4-.1-.6 0-.7-.2t-.6-.1-.5-.2-.6-.2-.6-.2-.6-.2q-.5.1-.6-.2t-.6-.2-.6-.2q0-.5-.8-.2t-.6-.2q.4-.6-1.6-.5-.5 0-.5-.3t-1 0q-1.2.1-.7-.4.3-.5-.4-.3-.5.3-.6-.1-.1-.3-1-.1-1.2.3-.8-.3t-.5-.2-.8-.2q0-.3-.6-.2t-.8-.2-.8-.2-.6-.2-.8-.2q-.6 0-.7-.2t-1-.2q-1 .3-1-.2 0-.3-1-.2-1 .2-1-.1 0-.5-.7-.2-.8.1-.8-.2t-.7-.4c-2.9-.1-3.5-.2-3.3-.5q0-.3-.7 0-.8 0-1.1-.2c-.4-.6-2.9-1-2.5-.4q.3.6-.4 0t-1.4-.3-.8-.1-1-.2q-.8.1-1.2-.2c0-.2-.7-.3-1.2-.2q-1 .2-1.6-.3-.5-.3-1.9-.2-1.2.3-1.3-.1 0-.4-.5-.4-.3 0 0 .5.1.5-.3 0-.6-.4-1.7-.3-1 0-1.3-.2c0-.2-1.1-.3-2.3-.2q-2 0-2.3-.2c-.3-.4-28.8-.4-28.8 0M114 19.1q-.7.1-.7.5t-.4.1q-.4-.1-.4.2 0 .5-.4.2-.4-.1-.4.2t-.4.2q-.3-.1-.4.2 0 .3-.4.2-.3-.1-.3.2t-.4.2-.4.2-.4.2-.4.2-.3.3c-.3-.4-2.4.8-2.4 1.3q0 .4-.3.2t-1.2.6-.7.4q.3-.6-.7 0-1 .4-.8.8t-.2.1q-.4-.2-.9.3l-1.1.6q-.6.1-1 .8l-1 .7c-1 0-1.9.6-1.7 1q.1.1-.4.4t-.4-.2q.3-.4-.4.3-.5.6-.6.4t-.6.4-.5.4-.8.6q-.8.7-1.2.5t-.6.4-.8.4-.5.4-.4.4-.7.3q-.1.6-.7.4t-.6.5q0 .6-.2.4-.3 0-1 .7t-1.2.8c-.9 0-3 1.5-3.3 2.3q-.4.8-.8.8-.5-.1-.5.3t-.4.1q-.4-.1-.3.1 0 .3-.2.3l-.9.8q-.5.6-.3.2t-1 .4q-1 1-1.2 1.4 0 .4-.7.4t-1 .8q-.6.8-.8.7c-.3-.4-1.8 1-1.8 1.7q0 .4-.4.3-.3-.2-.5.4-.4.5-.7.5-.5 0-1 .8t-.5.6-.8.5q-.7.9-1 .8t-1.3 1.2q-.7 1.2-.8 1c0-.2-.8.5-1.6 1.4q-1.5 1.6-1.4 1.2.3-.6-.5.1l-.7 1q0 .5-1.8 2.2l-2 2 1.9-2.1c1-1.1 1.8-2 1.5-2-.2 0-1.4 1.2-2.7 2.6q-2 2.3-1.7 2.2t-1 1.2c-.9.8-1.5 1.7-1.5 1.9q.1.2-.3 0-.3 0-.4.2 0 .3-.5.4-.6 0-.6.4t.4.2.2.2q-.3.3-.6.2-.4-.1-1.2 1-.8 1-.5 1.2.3 0-.7.5-.8.5-.8 1 0 .3-.5.7-.6.1-.4.5.1.3-.3.4-.7 0-1.1.7-.7.8 0 .3t0 .2q-.6.7-.5.9.2.2-.4.2c-.7 0-1.6 1.3-1.2 1.7q.2.3-.3.3c-.5 0-1.7 1.4-1.7 2q-.1.5-.8.7-.8.3-.2.4.7 0-.2.7-.7.7-.8 1-.1.5-.8.8c-.8.4-2 2.3-2.1 3.2 0 .6-1.2 1.7-1.9 1.7q-.7-.1 0 .4t-.2.4q-.7 0-.5.6.3.6-.1.4t-.4.2q.1.9-.9 1.5a3 3 0 0 0-.9 1.6q0 .9-.6 1.3-.4.5-.1-.3.4-1-.2-.1-.4.7-.3 1 .3.4-.4.6-.5.3-.4.5.3.2-.4.8-.6.5-.2.3.5-.2.2.4-.1.5-.5.4c-.3-.2-1 1-.8 1.6q0 .4-1 1.1-.8.7-.8 1.2.2.5-.4.7-.5.3-.4.9.2.5 0 .4-.4-.1-.8.8-.6 1 0 .7.3-.2-.5.7l-.7 1q.3.1-.7 1.1-.8 1-.8 1.5.2.5-.4.8-.6.2-.3 1 .2.7-.3.7t-.4.5-.3.5c-.4-.2-.8 1-.6 1.4q.2.4-.1.4-.5 0-.5.6t-.4.6 0 .3q.8.5-.1.4t-.2.4q.6.4 0 .4-.4.1-.4 1t-.4.8q-.5-.5-.6 1 0 .5-.7 1.2-.6.8-.7 1.2 0 .5.4-.1t.4-.1-.8.9-.5.8q0 .3-.2.3-.3.1-.3 1t-.2 1q-.3 0-.1.4 0 .4-.3.4t-.2.6-.4 1.1-.5 1.1q.2 1.5-.4 1.3-.3-.2-.1.4 0 .5-.3.6-.5 0-.3.7.2.8-.2.6-.3-.2-.2.4.3.5-.1.6-.3 0-.2.4.3.4-.4 1.3t-.2.5-.1.5-.2.6-.2.5-.5 1.5q.1.5-.1.6t-.2.5q.2.6-.2.6t-.3.8-.2.5-.2.4 0 .7q-.5 0-.3.8 0 .7-.3.7-.5 0-.5 1.4T7 147t-.1.5q.1.6-.2.9t-.2.8-.2.5-.1.6-.2.8-.2.6q.1.3-.2 1-.5.6-.3 1v.9q-.5.1-.6 1-.1.7.1.5.8-.4-.2 1.5c-.7 1.4-1.4 4.7-1.1 5.7q.2.8-.3 1.5l-.2.5q.3.1-.1.5-.4.6-.3 1.3c0 .4-.1 1.4-.4 2q-.4 1.2-.1 1.1.3-.2.3.4 0 .5-.3.7-.3.4-.2 1.8.1 1.6-.4 1.5c-.4 0-.5 0 0 1.8q.2 1-.2 1t-.4.5.5 0 0 .4-.4 1.6q.1 1-.2 1.3c-.2.1-.2 1.2-.1 2.3q0 2-.2 2.1a300 300 0 0 0 0 29.6q-.7.7-.1.4t.5.3-.4.4q-.6-.3-.1.5.3.8.2 1.2-.1.6.3 1.1t.1.4-.4.3.4.3.1.5q-.1.7.3 1.3.5.8 0 .3-.5-.1-.5.1 0 .5.4.5t.1 1.3q-.1 1.3.2 2 .5.5.3 1.4 0 .9.3 1.6.5.7-.1 1t.2.8.2 1q-.5.9.3 1.3l.2.3q-.4 0-.4 1.2 0 1.3.6 1.3t.2 1q0 1 .1.9c.3-.2.4.4.5 3.3q0 .6.4.7t.2.8.2.8q.3 0 .1 1t.2 1 .5.3-.4.2q-.3 0-.1.6t.6.8q.5 0 0 .4c-.6.6-.2 1.6.4 1.2q.4-.2 0 .4-.7.6 0 .8t.4.9q-.1.5.2.6.5 0 .2.8t.2.6c.6-.4.5.6 0 1.2q-.6.5.1.5t.4.6q-.2.7.3.4.6-.5.3.7l.1 1q.3 0 .3.5 0 2 .5 1.7c.5-.4.5.3 0 .9q-.7.4.1.4t.5.6q-.1.5.2.6t.2.6.3.7-.1.8q-.8.8.2.4.7-.3.4.3-.1.7.3.9t0 .2q-.6 0-.2.7.3.8.1 1-.2.4.4.1.8-.3.5.7-.2 1 .4 1.2.9.1.1.9-.7.8.2.4.6-.3.7.1 0 .3-.4.4-.2.1.4 1.3l1 2.4c.1 1.2.9 2.5 1.4 2.5q.3 0 .1.4-.2.6.5 1.5t.6 1.6q0 .4.3.4t.2.4.4.6.6 1.2.4 1 .1.4q0 .3.2.3t.2.7q-.3.6.2.4.3-.3.2.2-.2.6.4 1.2.5.6.3.8-.1.3.3.3.3 0 .2.3t.2.5.5 1.2q0 1 .4 1 .3.1 0 .5t.4.2.4.2q0 .5.9 1.6t.6 1q-.5-.2-.5 0 .1.5.5.7.5.3.6 1 0 .9.7 1.4.5.4.2 0l-.4-.8c0-.5 1 1 1 1.5l.1 1q0 .3.4.2.4-.2.6.4t-.2.3 0 .6.8.6.5.3v1.1q.1.5.6.5.6-.1.4.4-.2.7 1.1 2t1.1 1.9q-.3.4.2.1t.4.6.6 1q.5.2.4.6c-.3.4.5 1.6 1 1.3l1 1q.8 1 0 .5-.6-.6-.8-.1-.2.3 0 .4c.8 0 3.4 2.6 3.2 3.2q-.1.5.3.8.5.2.6.6c0 .6 1.4 2 1.8 1.7q.1-.2 0 .2t.7 1.4q.8.9.7 1.2t.4.2q.5 0 .9.4.2.4-.5.2-.5-.2.8.8c1.4 1 2 1.7 1 1.2q-.4-.2.2.3t.3.7.8 1.1a3 3 0 0 0 1.6 1q.4-.3.2 0t.8 1.3q.8.8.3.4-1-.8-.3.3.6.8 1.1.6.6-.1.4.2-.2.5.4 1t.8.9q0 .3.4.4.3 0 .7.3.3.4-.1.1-1-.5 0 .7.4.4.9.4.4-.1.7.3.4.4-.2.1-.3-.1.2.8t1 .8s.9.6 1.7 1.5q1.5 1.5.4.6-1-1 .6 1 1.7 1.9 2 1.6.5-.5.4.7 0 .2.5.2t.3.4.3.3c.5-.3 1.7 1.2 1.4 1.8q-.3.5 0 .2.4-.2 1.1.4t.5.1q-.4-.6.1-.2t.3.8c-.2.5.5 1.3 1 1.3q.3 0 0-.5 0-.3.2-.1.3.3.3.8.1.4.5.4.6.1 1.1 1t.6.4.3.4 1 1 1 .7q0 .8.4.2t.4 0c0 .9 1.8 2.5 2 1.9q.3-.4.3.2t.4.5.6.2q.3.5-.1.2t-.5 0 1.2 1 1 .2l.3.2q.5.7.9.4.2-.2 0 .4-.1.6.2.7 1-.2 1.2.6.3.5.8.3.3-.1.2.1-.1.4.7 1.3.9.7 1 .4t1 .7q.8.9.9.5.1-.3 1.6 1 1.4 1.6 2.2 1.6.7 0 .6.4t.7.5.6.3q-.1.2 1 .7t1.2.9.5.2q.5-.2.5.5t.7.7 1.2.6q.4.4.9.3.3-.2.4.3 0 .5.3.6 1.7.1 2.1 1 .4.5.9.3.5-.1.7.7.3.9 1 .5.8-.3 1.5.8.6.9 1 1t1.2.6.7.3-.5-.7q-.5-.1 0-.2.4 0 1 1t1.4.8.7.3q0 .3.8.4.8 0 .6.6t.2.2q.6-.1 1 .2.7.4 1 .2.6-.3.2.2t.3.3.4.4.8.4 1.4.5 1.2.5.8.2.6.2.8.3-.2.2-.4.1 1 .3h.8c-.3.3 1 1.3 1.7 1.3q.8.1 0-.4-.6-.4 0-.4.3 0 .7.6.2.6.6.5 1.6-.1 1.3.4c-.3.5 1 1.2 2 1.2q.9.1-.2-.4-1.8-.9.3-.3 1 .4 1.2.8 0 .3.6 0t.4.3q-.2.3.3.2.5-.2 1.1.4.8.6 1.8.7a4 4 0 0 1 1.8.6q.5.4.7.2.3-.1.3.3t.8.2.5.3.6.2q.8-.2.6 0c-.1.3 1 1 1.9 1l.5.3q.4.2.9-.2.7-.6.3 0t.3.4h.6q.1.3 1.3.4 1 .1 1.5.5.3.5 1.5.5t1.2.4.5.2c1.4-.1 2.7.1 2.4.5q-.3.5.8.2 1-.2.8.1-.3.5.8.2t.8.2.8.2.7.2.5.3 1 .4q.3.5.9.5t.3-.5q-.2-.4.4 0 .6.6 1.2.4t.8.4.7.2c.5-.6 1.6-.7 1.3-.1q-.2.3.8.2 1-.3.7.2t.3.3q.5-.2 1 0c.5.6 3 1 2.6.5q-.1-.4.2-.4t.4.4q0 .4 1.1.2t1.4.1.6.3.6.2.6 0q.3-.8 1.1.1t1.3.3c.8-.6 1.9-.4 1.6.3q-.3.6.5.3 2.4-.9 2.5-.3 0 .4.4.4t.2-.5q-.4-.5.2 0t1.6.3q.8 0 1.4.3c.2.1 1.4.2 2.6.1a272 272 0 0 0 30.5.1q.6.5.8.2t1-.2q2 .6-1.3-2.4-1.8-1.7-1-1.2l1 .8-1-1q-1-1.1-1.4-1.2a1 1 0 0 1-.8-.4q-.3-.5.2-.2t-.2-.4-1-1.4-1-.7q-.5 0-.4-.3.2-.4-.8-1.3-1-.7-.5-.5.5.3.2-.2-.2-.3-.9-.4-.5 0-.4-.3.2-.3-.6-1-.7-.6-.3-.5.6.3.3-.1t-1-.5q-.4 0-.3-.2 0-.4-.6-1t-.3-.5-.8-1-.8-1q.6.3.3-.1-.4-.5-.9-.5t-.4-.3-.3-.6-.5-.7-.3-.5q-.4 0-1.2-1l-.7-1 1 .8q.5.5-.9-1.4l-2.2-2.5q-.4-.5-.3-.7c.1 0-.5-1-1.5-1.9q-1.5-1.6-1.5-2.2 0-.4-.7-1l-1.7-1.6q-1-1.4 0-.6.8.8-.3-.7-.8-1.2-1.2-1.3-.3 0-.1-.4.1-.3-.4-.6t-.4-.6-.4-.5q-.5-.3-.4-.6.2-.4-.4-.6-.5-.2-.4-.6.2-.4-.3-.6t-.5-.6-.6-.7q-.7-.5-.6-1 .2-.6-.1-.4-.6.1-.4-.7c.2-.8-.9-1.8-1.2-1.6q-.3 0-.5-.4-.3-.6.2-.4l-.6-.7q-1.7-1.7-.6-1.3.4.2-.2-.3-.8-.7-.8-1.1 0-.6-1-1.5-.7-1-.6-1.4 0-.6-1-2-1.2-1.3-.9-1.1.6.3.3-.4-.2-.5-.6-.6t-.2-.3q.3-.5-.5-1.2-.6-.6-.5-1 .2-.1-.3-.2-.3 0-.2-.4.1-.3-.1-.4-.4-.1-.7-1.1-.2-1.1-.6-1.2t-.2-.4-.2-.4-.2-.4 0-.4-.4-.8q-.1-.9-.5-1.1t-.5-.6q.2-1-.3-.8-.7.1-.4-1.7 0-.4-.4-.3-.3.2-.1-.3 0-.6-.2-.6-.5 0-.4-.3c.1-.9-.1-1.7-.4-1.5-.5.3-1.3-2-1-2.6q.2-.4-.2-.1-.6.3-.3-.3.1-.6-.2-1l-.1-.5q.1-.3-.2-.4-.4 0-.1-.6.1-.7-.3-.4-.6.4-.2-.5.1-.8-.2-.8t-.3-.6q.2-.5 0-.6c-.5 0-1.4-2.9-1.3-4q0-.7-.4-.4t-.3-.8v-1q-.4 0-.2-.6.1-.5-.2-.6-.5 0-.3-.6t-.2-1.2-.2-1.2q.3-.5-.2-.3t-.2-.7q.2-1-.6-1.5t-.5 0q.5.9-.7-.2c-.6-.5-1.3-.7-3.3-.9q-.4 0-.3-.4.4-.6-1.4-.5a1 1 0 0 1-1-.5q-.3-.6-.7-.5-.5.2-1-.3a1 1 0 0 0-1-.3q-.7.2-.4-.2.4-.6-.8-.4l-.5-.4c-.3-.6-3.4-2-3.7-1.7q-.2 0-.2-.2t-.6-.7q-.6-.2-.4.3.3.4-.7-.5t-1-.6-.5-.3q-.3-.6-.7-.5t-1.4-.8q-.9-.8-1.3-.8-.4.2-.6-.3t-.6-.4-.6-.4-.6-.4-.4-.1q-.1-.4-1-1-1-.8-.8-.2.2.5-.3-.3-.7-.7-1-.6t-.4-.3-.4-.3q-.4-.1-1.4-1.1t-.7-.6q.1.5-.7-.4t-.6-.4q.2.4-1.3-1.1l-1.3-1.2q.3.6-.3 0t-.9-.5-.2-.4c0-.7-2.2-2.5-2.8-2.3q-.3 0-.2-.2a39 39 0 0 0-7.9-7.8q0-.5-.7-1.1t-.1-.4-.2-.5-1.3-.9q-.6 0-.4-.2t-.4-.9-.1-.3q.4.2-1-1.1t-1-1.2-1.1-1.9a9 9 0 0 0-2-2.2q-.3 0-.2-.4.2-.3-.5-.7-.8-.5-.8-1.3 0-.6-.4-.5-.3.1-.4-.6 0-.7-.6-1l-.6-.7c0-.7-.5-1.4-.8-1.2q-.2 0-.5-.4-.2-.7.2-.4t-.3-.4q-.7-.5-.7-1.1t-1-1.4q-.7-1-.6-1.5t-.2-.5-.3-.3c.2-.5-1-2.8-1.3-2.6q-.3.2 0-.5.1-.6-.3-.3t-.2-.4q.3-.7-.2-.4t-.2-.4q.1-.5-.2-.6t-.4-.3q.3-1.2-.4-1-.4.1-.4-.3c.2-1.2 0-2-.4-1.6q-.5.1-.2-.2.1-.5-.3-1-.6-.7-.4-1.2t-.2-.6q-.5 0-.3-.4.3-.3-.1-.4-.3 0-.2-.6.3-.6-.1-.4t-.6-.6q-.2-.6.1-.5.3.2.1-.4-.2-.5-.6-.6t-.2-.6-.2-.4q-.4.3-.1-.6t-.1-.6-.2-.6q.2-.6-.3-.7t-.2-.6q0-.5-.2-.6t-.2-.8-.2-.8 0-.6q0-.7-.3-.4-.5.3-.3-.6c0-.5-.3-2-.8-3.4s-.8-3-.7-3.5q.2-.8-.2-.8t-.2-1-.2-1-.2-1.2q.3-1-.2-1.1-.4 0-.3-.7 0-.7-.3-1.3-.3-.5.2-.2t0-.5-.2-1.6q0-.7-.2-.8t-.2-2v-2a176 176 0 0 1 .4-24.1q0-1.5.3-1.3.4.2.1-.9-.2-1 .3-1.7t-.1-.2q-.7.4-.1-.3.5-.5.2-.9-.1-.2.2-.6c.3-.1.6-1.2.6-2.4s.3-2.5.6-3q.4-.7.4-1.3-.2-.5.4-.4t0-.7q-.3-.7 0-.8t.1-1q-.1-1.2.3-.7.6.2.3-.4-.1-.5.2-.6t.1-.8q-.1-.8.2-.8.5 0 .3-.8-.1-.8.2-.5t.2-.6q-.1-.7.2-.6.4.3.2-.6t.2-.5q.4.2.2-.4t0-.7.2-.6q-.3-.7.3-.4.5.4.2-.1t0-.8q.5-.3.6-1t.3-1c.5-.4 1.6-3.1 1.2-3q-.4.2-.1-.3.1-.5.5-.6.3 0 .1-.6t.5-.8q.5-.2.4-.8t.2-.3q.6.3.2-.4-.1-.6.1-.4c.4.2 1-1 .6-1.4q0-.4.2-.4.5 0 .3-.3-.2-.4.4-.6.5-.3.4-.9-.2-.5.1-.3t.5-.3c0-1.2.1-1.4.8-2q.7-.7.4-1.1-.1-.4.2-.2.5.3.5-.1l.2-.8.1-.8q0-.3.4-.2t.4-.2q0-1 .6-1.3t.6-1 .6-1.4q.6-.6.4-.2-.3.5.5-.4.7-.8.6-1.4t.8-1.1q1-.7 1-1.2.1-.5.8-1t.7-.6.7-1.2.8-1.4q0-.5.4-.5c.6 0 2.1-2 1.8-2.3q-.2-.3.2 0 .4 0 1-.8.8-.9 1.2-.7t-.2-.5-.1-.5a41 41 0 0 0 8.6-8.5q.6.1 2.2-1.4l2-1.8q.4 0 .4-.6 0-.4.5-.5t.8-.5l.7-.6q.3 0 .3-.4-.1-.3.4 0 .7 0 1-.6.5-.7 1-.8.5 0 1.2-1t1.1-.8q.6 0 1.4-.6.9-.7.4-.5t.2-.4 1.4-.6 1-.6q.4-.6.7-.6 1.2.2.8-.4-.1-.3.2-.3.9 0 1.5-.8t.2 0 .4 0q.6-.5.7-.2t.4-.5 1-.8c.4 0 .6-.4.7-2.7.1-1.6 0-2.9-.2-2.9q-.2-.1-.2-2 0-1.7-.2-1.9t-.2-1.3q.1-1.3-.2-1.4t-.1-1q.1-1-.1-.9-.4.2-.4-1.2l-.2-2q0-.8-.3-.8-.3-.1-.4-.8c0-1.8-.2-2.5-.5-3q-.3-.4-.1-.8 0-.4-.2-.4t-.2-.6q.2-.5-.1-.6t-.4-1.2-.3-1.5q-.7-.5-.7-2 0-.8-.3-.8t-.1-.6q.1-.5-.2-.5t-.2-.6-.2-.6-.2-.6-.2-.6q-.5 0-.2-.4.1-.4-.4-1t-.5-1.2-.1-.5-.1-.7-.3-.3q-.6.3-.2-.6t-.2-.6-.4-1.1c0-.6-.9-2.7-1.5-3.2q-.5-.5-.6-1.5l-.2-1.5q0-.3-.4 0-.3 0-.5-.6c0-1.9-.7-3.3-1.2-3q-.4.2-.2-.3.1-.6-.3-1t-.3-.9-.3-.3-.2-.4-.2-.4-.2-.4c.3-.4-.5-2.4-1-2.4q-.3 0-.1-.4.1-.3-.2-.3t-.3-.3c.2-.6-1-2.9-1.3-2.6q-.3 0-.1-.4.2-.6-.4-.9a1 1 0 0 1-.7-1 1 1 0 0 0-.6-.9q-.5-.1-.3-.6c.3-.5-.9-2.7-1.5-2.7q-.3 0-.2-.3c.4-.3-.7-2.3-1.4-2.6a1 1 0 0 1-.4-.8q.2-.6-.4-.8-.5-.4-.8-1.4-.2-1-.6-1-.4.3-.4-.4c0-.9-1-2.2-1.3-1.8q-.2.1-.5-1t-.8-1.5q-.5-.2-.3-.6t-.4-.6q-.5-.1-.4-.5 0-.3-.4-1c-.6-.9-1-1-2.6-.6m6.7 99-1.5 1.5-1.4 1.3 1.3-1.5q1.8-1.8 1.6-1.3M281 280.8q-1.7 1.6-2 1.7 0-.2 1.6-1.7l1.9-1.8z"/><path d="M308 31.8q.8.6 1.1.6.2 0-.3-.6l-1.2-.5q-.2 0 .4.5m30.9 24.5 1.7 1.5-1.3-1.5q-1.5-1.6-1.8-1.6 0 .2 1.4 1.5M58.4 58.8l-2 2 2.1-1.9c1.9-1.8 2.2-2.2 2-2.2zM343.6 61q1.4 1.5 1.7 1.6l-1.4-1.6-1.7-1.5q0 .2 1.4 1.5m21 26q.6 1 1 .8 0-.3-.7-1l-1-1zm2.1 2.8q.1.6.8 1.6t.8.8l-.8-1.6q-.7-1-.8-.8M135 106.1q-1.2.9-.4.6c.7-.4 2-1.6 1.7-1.6q-.3 0-1.3 1m-16 13.3-1.3 1.5 1.4-1.3 1.5-1.5q.2-.5-1.6 1.3m266.1 5.6q.5 1.1.6 1c.2-.1-.5-2.2-.8-2.2zm.8 1.8q0 .4.5 1.3t.6.6l-.6-1.4q-.5-.8-.5-.5m-280.2 8.5q-1 1.3-.2.7c.7-.6 1.6-2 1.3-2zm293.9 56.1q0 1.2.2.7v-1.4q-.2-.5-.2.7m-85.9 8.4q0 2.3.2 1.3v-2.8q-.2-.9-.2 1.5m85.9 8.8q0 1.1.2.7v-1.4q-.2-.5-.2.7m-8.4 49.3q-.3 1-.1 1.4l.4-1.1q.2-1.1 0-1.4zm-110.8 22.9-1.6 1.7 2-1.7q1.6-1.7 1.5-1.8zm-249.1 27 .5 1q.6.7.6.4 0-.4-.6-1.1-.5-.6-.5-.4m131.7 1.2q0 .7.3 1.6c.4 1 .4 0 0-1.4q-.4-1.2-.3-.2m5 16.8.8 2q.6 1.2.5.5c-.3-1-1.3-3.1-1.3-2.5M55.5 338.4l1.2 1.3 1.3 1.1-1.1-1.2q-1.5-1.7-1.4-1.2m285.7 3.1-1.6 1.7 1.7-1.6c1.6-1.4 1.8-1.8 1.6-1.8zm-280.5 2.3 1.8 1.5-1.4-1.6-1.7-1.5zm123.9 14q.6 1.1.8 1.2l-.4-1.2-.8-1.2q-.2.2.4 1.2m79.9 7q.6 1.5 1 1.6l-.7-1.6q-.6-1.4-1-1.5zm-177.9 0q.8 1 1.1.8 0-.3-.9-1l-1-.6zm104.4 2.6 1 1.3c.4 0-.6-1.5-1.2-2q-.7-.5.2.7m-100.6 0 1.6.9q.3-.1-.8-.8l-1.6-.8q-.2.1.8.8m33.4 17.4c0 .3 2 1 2.3.8l-1-.6zm3.5 1.5 1.4.6q.3 0-.6-.6t-1.3-.5q-.3 0 .5.5m63.4 13.4h1.4q.5-.2-.7-.2t-.7.2m17.2 0h1.4q.5-.2-.7-.2t-.7.2"/></g></svg>
@@ -0,0 +1,382 @@
1
+ <template>
2
+ <div
3
+ ref="rowRef"
4
+ class="flex w-full justify-between items-center"
5
+ >
6
+ <!-- shrink-0 keeps the label at its natural width: letting flex shrink it by the fraction
7
+ of a pixel that rounding introduces is enough for Chromium to ellipsize a label that
8
+ fits. The cap is what makes an outsized label ellipsize instead of eating the row. -->
9
+ <div
10
+ v-if="label"
11
+ class="min-w-0 max-w-[45%] shrink-0"
12
+ >
13
+ <label
14
+ ref="labelRef"
15
+ class="block truncate text-start mr-6"
16
+ :title="label"
17
+ :class="theme === 'dark' ? 'text-white' : 'text-black'"
18
+ >{{ label }}</label>
19
+ </div>
20
+ <div v-else />
21
+ <slot name="insetElement" />
22
+ <!-- Shrinks far more eagerly than the label, so a tight row ellipsizes the button names
23
+ before it starts eating into the label. -->
24
+ <div class="flex items-center min-w-0 shrink-[1000]">
25
+ <div
26
+ v-if="infoTooltip"
27
+ class="relative group inline-flex items-center shrink-0 mr-2"
28
+ >
29
+ <span
30
+ class="mdi mdi-information-outline text-[16px] opacity-60 cursor-help"
31
+ :class="theme === 'dark' ? 'text-white' : 'text-black'"
32
+ />
33
+ <div
34
+ class="absolute bottom-full mb-1 right-0 hidden group-hover:block w-max max-w-[280px] px-2 py-1 text-xs rounded bg-gray-700 text-white z-[1000]"
35
+ >
36
+ {{ infoTooltip }}
37
+ </div>
38
+ </div>
39
+ <div
40
+ ref="trackRef"
41
+ class="relative flex min-w-0 justify-end overflow-hidden rounded-[6px] bluevue-elevation-1 z-[666]"
42
+ :class="[theme === 'dark' ? 'bg-[#464646AA]' : 'bg-[#00000011]', disabled ? 'opacity-30 pointer-events-none' : '']"
43
+ :style="{ height: height || (density === 'compact' ? '24px' : '30px') }"
44
+ >
45
+ <div
46
+ id="border-releif"
47
+ class="absolute left-[-20px] top-0 h-full w-[6px] bg-[#6699cc] z-[20] pointer-events-none"
48
+ />
49
+ <template
50
+ v-for="(btn, idx) in buttonItems"
51
+ :key="btn.name"
52
+ >
53
+ <button
54
+ :disabled="disabled || btn.disabled"
55
+ :title="btn.name"
56
+ class="flex min-w-0 items-center justify-center text-sm font-medium transition-colors duration-200"
57
+ :class="[
58
+ // A group with no room left falls back to the tightest inset whatever the
59
+ // density asks for, since the alternative is cutting into the names.
60
+ isTight ? DENSITY_PADDING.compact.class : DENSITY_PADDING[density || 'comfortable'].class,
61
+ // The active choice is the one worth reading at a glance, so it keeps its full
62
+ // name and the rest give up the room a crowded group needs.
63
+ selected[idx] ? 'shrink-0' : '',
64
+ selected[idx] ? 'text-white' : theme === 'dark' ? 'text-[#ffffff99]' : 'text-[#00000066]',
65
+ selected[idx] && type === 'switch' ? 'bluevue-elevation-5' : '',
66
+ disabled || btn.disabled ? 'cursor-not-allowed' : 'cursor-pointer',
67
+ // Only the button's own state fades it: a disabled group is faded whole by the
68
+ // track below, and dimming twice over would leave the names unreadable.
69
+ btn.disabled ? 'opacity-30' : '',
70
+ ]"
71
+ :style="{ backgroundColor: selected[idx] ? btn.activeColor || 'var(--bluevue-primary)' : undefined }"
72
+ @click="onButtonClick(idx)"
73
+ @contextmenu.prevent="requestContextMenu(idx, $event)"
74
+ @pointerdown="startLongPress(idx, $event)"
75
+ @pointerup="cancelLongPress"
76
+ @pointerleave="cancelLongPress"
77
+ @pointercancel="cancelLongPress"
78
+ >
79
+ <div class="relative group inline-block min-w-0">
80
+ <p
81
+ data-bbg-label
82
+ class="truncate"
83
+ :class="[density === 'compact' ? 'text-[10px]' : 'text-xs', isWide ? 'max-w-[150px]' : '']"
84
+ >
85
+ {{ btn.name }}
86
+ </p>
87
+ <div
88
+ v-if="btn.tooltip"
89
+ class="absolute bottom-full mb-1 left-1/2 -translate-x-1/2 hidden group-hover:block whitespace-no-wrap px-2 py-1 text-xs rounded bg-gray-700 text-white"
90
+ >
91
+ {{ btn.tooltip }}
92
+ </div>
93
+ </div>
94
+ </button>
95
+ <div
96
+ v-if="idx < buttonItems.length - 1"
97
+ class="w-[1px] shrink-0 bg-[#FFFFFF22] my-2"
98
+ />
99
+ </template>
100
+ <div
101
+ v-if="buttonsMenu?.length"
102
+ class="w-[1px] shrink-0 bg-[#FFFFFF22] my-2 mr-[3px]"
103
+ />
104
+ <template v-if="buttonsMenu?.length">
105
+ <button
106
+ ref="menuAnchorRef"
107
+ v-bind="menuActivatorProps"
108
+ type="button"
109
+ title="More options"
110
+ class="shrink-0 px-0 flex items-center justify-center h-full cursor-pointer"
111
+ :class="theme === 'dark' ? 'text-white' : 'text-black'"
112
+ >
113
+ <span class="self-center mdi mdi-menu-right text-[20px] mr-[2px] opacity-80" />
114
+ </button>
115
+ <div
116
+ :id="menuPopoverId"
117
+ ref="menuPopoverRef"
118
+ popover
119
+ class="bluevue-popover"
120
+ :style="menuFloatingStyles"
121
+ @toggle="onMenuToggle"
122
+ >
123
+ <ul
124
+ class="bluevue-elevation-5 max-h-[60vh] overflow-y-auto border-[1px] rounded-[4px] border-[#FFFFFF22]"
125
+ :class="[
126
+ theme === 'dark' ? 'text-[#FFFFFF99] bg-[var(--bluevue-surface)]' : 'text-black bg-white',
127
+ isMenuPositioned ? 'opacity-100' : 'opacity-0',
128
+ ]"
129
+ >
130
+ <li
131
+ v-for="(item, idx) in buttonsMenu"
132
+ :key="item.name"
133
+ >
134
+ <button
135
+ :disabled="item.menuItemDisabled"
136
+ type="button"
137
+ class="block w-full text-left whitespace-nowrap px-4 py-2 text-[14px]"
138
+ :class="[
139
+ idx < buttonsMenu.length - 1 ? 'border-b border-white' : '',
140
+ theme === 'dark' ? 'hover:bg-[#333333]' : 'hover:bg-gray-100',
141
+ item.menuItemDisabled ? 'opacity-30 cursor-not-allowed' : 'cursor-pointer',
142
+ ]"
143
+ @click="runMenuItem(item)"
144
+ >
145
+ {{ item.name }}
146
+ </button>
147
+ </li>
148
+ </ul>
149
+ </div>
150
+ </template>
151
+ </div>
152
+ </div>
153
+ </div>
154
+ </template>
155
+ <script setup lang="ts">
156
+ import { nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'
157
+
158
+ import { useBluePopover } from '../composables/useBluePopover'
159
+
160
+ /**
161
+ * One button in the group
162
+ */
163
+ interface ButtonItem {
164
+ /** Name of the button, displayed as text */
165
+ name: string
166
+ /** Optional tooltip text displayed on hover */
167
+ tooltip?: string
168
+ /** Whether this button is pre-selected (only for 'switch' type) */
169
+ preSelected?: boolean
170
+ /** Optional color for the button when active */
171
+ activeColor?: string
172
+ /** Whether the button is disabled */
173
+ disabled?: boolean
174
+ /** Callback when the button is selected */
175
+ onSelected?: () => void
176
+ /** Custom options to handle button item press */
177
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
178
+ options?: Record<string, any>
179
+ }
180
+
181
+ /**
182
+ * One item in the menu
183
+ */
184
+ interface MenuItem {
185
+ /** Name of the menu item, displayed as text */
186
+ name: string
187
+ /** Callback when the menu item is clicked */
188
+ action: () => void
189
+ /** Disable the menu item */
190
+ menuItemDisabled?: boolean
191
+ }
192
+
193
+ const props = defineProps<{
194
+ /** List of buttons in the group */
195
+ buttonItems: ButtonItem[]
196
+ /** Optional menu items to display in a dropdown */
197
+ buttonsMenu?: MenuItem[]
198
+ /** Whether the entire button group is disabled */
199
+ disabled?: boolean
200
+ /** Theme of the button group */
201
+ theme?: 'light' | 'dark'
202
+ /** Type of button group, 'switch' for single selection or 'toggle' for multiple selections */
203
+ type: 'switch' | 'toggle'
204
+ /** Height of the button group container */
205
+ height?: string
206
+ /** Label text on the left side of the button group */
207
+ label?: string
208
+ /** Optional info tooltip shown via an info icon next to the control. */
209
+ infoTooltip?: string
210
+ /**
211
+ * How much room each button gives its name (default 'comfortable'). 'compact' also makes the
212
+ * group shorter and its labels smaller, for rows where the group is a secondary control.
213
+ */
214
+ density?: 'compact' | 'regular' | 'comfortable'
215
+ }>()
216
+
217
+ const emit = defineEmits<{
218
+ (e: 'update:selected', value: boolean[]): void
219
+ /**
220
+ * A button was right-clicked or held down, with the pointer position to place a menu at.
221
+ * Emitted instead of the selection, so holding a button never also activates it.
222
+ */
223
+ (e: 'context-menu', value: { item: ButtonItem; index: number; x: number; y: number }): void
224
+ }>()
225
+
226
+ const selected = ref<boolean[]>([])
227
+
228
+ const {
229
+ anchorRef: menuAnchorRef,
230
+ popoverRef: menuPopoverRef,
231
+ popoverId: menuPopoverId,
232
+ activatorProps: menuActivatorProps,
233
+ isPositioned: isMenuPositioned,
234
+ floatingStyles: menuFloatingStyles,
235
+ hide: hideMenu,
236
+ onToggle: onMenuToggle,
237
+ } = useBluePopover()
238
+
239
+ // Long enough not to fire on a normal tap, short enough to feel like a press-and-hold.
240
+ const LONG_PRESS_MS = 500
241
+ let longPressTimer: number | null = null
242
+ let longPressFired = false
243
+
244
+ // The inset each density gives a button name, paired with the total width it costs so the
245
+ // measurements below can reason about the group without reading it back from the DOM.
246
+ const DENSITY_PADDING = {
247
+ compact: { class: 'px-2', total: 16 },
248
+ regular: { class: 'px-3', total: 24 },
249
+ comfortable: { class: 'px-4', total: 32 },
250
+ } as const
251
+
252
+ // Once the buttons' natural width would exceed this, cap each label so long names
253
+ // ellipsize instead of letting the group sprawl (or clip) past the panel.
254
+ const GROUP_WIDTH_LIMIT = 850
255
+ const LABEL_MARGIN = 24 // mr-6 on the label
256
+ const rowRef = ref<HTMLElement | null>(null)
257
+ const labelRef = ref<HTMLElement | null>(null)
258
+ const trackRef = ref<HTMLElement | null>(null)
259
+ const isWide = ref(false)
260
+ const isTight = ref(false)
261
+ let resizeObserver: ResizeObserver | null = null
262
+
263
+ const measureWidth = (): void => {
264
+ const track = trackRef.value
265
+ const row = rowRef.value
266
+ if (!track || !row) return
267
+ // Each label keeps its full text width in scrollWidth even while ellipsized, so the
268
+ // natural width is independent of the cap we apply, avoiding a measure/toggle loop.
269
+ const labels = track.querySelectorAll<HTMLElement>('[data-bbg-label]')
270
+ const padding = DENSITY_PADDING[props.density || 'comfortable'].total
271
+ let natural = 0
272
+ labels.forEach((label) => {
273
+ natural += label.scrollWidth + padding
274
+ })
275
+ natural += Math.max(0, labels.length - 1) // 1px separators between buttons
276
+ isWide.value = natural > GROUP_WIDTH_LIMIT
277
+
278
+ // Room the track could ever have: the row minus the label at full text width and whatever
279
+ // else sits beside the track. Measured that way, and always against the density's own
280
+ // padding, the answer does not depend on the padding currently applied, so it cannot
281
+ // oscillate between the two.
282
+ let occupied = labelRef.value ? labelRef.value.scrollWidth + LABEL_MARGIN : 0
283
+ for (const child of Array.from(row.children)) {
284
+ if (!child.contains(track)) continue
285
+ occupied += child.clientWidth - track.clientWidth
286
+ }
287
+ isTight.value = natural > row.clientWidth - occupied
288
+ }
289
+
290
+ const initSelected = (): void => {
291
+ const items = props.buttonItems
292
+ if (props.type === 'switch') {
293
+ const first = items.findIndex((b) => b.preSelected)
294
+ const idx = first >= 0 ? first : 0
295
+ selected.value = items.map((_, i) => i === idx)
296
+ } else {
297
+ selected.value = items.map((b) => !!b.preSelected)
298
+ }
299
+ emit('update:selected', selected.value)
300
+ }
301
+
302
+ const toggleButton = (idx: number): void => {
303
+ if (props.disabled || props.buttonItems[idx].disabled) return
304
+ const btn = props.buttonItems[idx]
305
+ if (props.type === 'switch') {
306
+ if (!selected.value[idx]) {
307
+ selected.value = selected.value.map((_, i) => i === idx)
308
+ btn.onSelected?.()
309
+ }
310
+ } else {
311
+ selected.value[idx] = !selected.value[idx]
312
+ if (selected.value[idx]) btn.onSelected?.()
313
+ }
314
+ emit('update:selected', selected.value)
315
+ }
316
+
317
+ const requestContextMenu = (idx: number, event: MouseEvent | PointerEvent): void => {
318
+ if (props.disabled || props.buttonItems[idx].disabled) return
319
+ emit('context-menu', { item: props.buttonItems[idx], index: idx, x: event.clientX, y: event.clientY })
320
+ }
321
+
322
+ const cancelLongPress = (): void => {
323
+ if (longPressTimer !== null) {
324
+ clearTimeout(longPressTimer)
325
+ longPressTimer = null
326
+ }
327
+ }
328
+
329
+ const startLongPress = (idx: number, event: PointerEvent): void => {
330
+ if (props.disabled || props.buttonItems[idx].disabled) return
331
+ cancelLongPress()
332
+ longPressFired = false
333
+ const { clientX, clientY } = event
334
+ longPressTimer = window.setTimeout(() => {
335
+ longPressTimer = null
336
+ longPressFired = true
337
+ emit('context-menu', { item: props.buttonItems[idx], index: idx, x: clientX, y: clientY })
338
+ }, LONG_PRESS_MS)
339
+ }
340
+
341
+ const onButtonClick = (idx: number): void => {
342
+ // The click that ends a long press must not also select the button it was held on.
343
+ if (longPressFired) {
344
+ longPressFired = false
345
+ return
346
+ }
347
+ if (!props.buttonItems[idx].disabled) toggleButton(idx)
348
+ }
349
+
350
+ const runMenuItem = (item: MenuItem): void => {
351
+ item.action()
352
+ hideMenu()
353
+ }
354
+
355
+ onMounted(() => {
356
+ initSelected()
357
+ nextTick(measureWidth)
358
+ // The first measurement runs against whatever font is available, and a fallback is wide
359
+ // enough to call a group crowded that is not. Measure again once the real font lands.
360
+ document.fonts?.ready.then(measureWidth)
361
+ if (typeof ResizeObserver !== 'undefined' && trackRef.value) {
362
+ resizeObserver = new ResizeObserver(() => measureWidth())
363
+ resizeObserver.observe(trackRef.value)
364
+ }
365
+ })
366
+
367
+ onBeforeUnmount(() => {
368
+ resizeObserver?.disconnect()
369
+ cancelLongPress()
370
+ })
371
+
372
+ watch(
373
+ () => props.buttonItems.length,
374
+ initSelected,
375
+ { deep: true, immediate: true }
376
+ )
377
+
378
+ watch(
379
+ () => props.buttonItems.map((item) => item.name).join('|'),
380
+ () => nextTick(measureWidth)
381
+ )
382
+ </script>
@@ -0,0 +1,72 @@
1
+ <template>
2
+ <div class="rounded-lg overflow-hidden">
3
+ <div
4
+ class="flex items-center justify-between bg-transparent cursor-pointer select-none px-3 my-2"
5
+ @click="togglePanel"
6
+ >
7
+ <div class="flex-1 flex items-center">
8
+ <div
9
+ class="flex-1 h-px"
10
+ :class="props.theme === 'dark' ? 'bg-[#ffffff22]' : 'bg-[#00000033]'"
11
+ />
12
+ <span
13
+ class="mx-3 min-w-0 truncate text-sm font-medium opacity-60"
14
+ :title="title"
15
+ :class="props.theme === 'dark' ? 'text-white' : 'text-black'"
16
+ >{{ title }}</span>
17
+ <div
18
+ class="flex-1 h-px"
19
+ :class="props.theme === 'dark' ? 'bg-[#ffffff11]' : 'bg-[#00000033]'"
20
+ />
21
+ </div>
22
+ <span
23
+ class="mdi ml-3 text-[24px] leading-none opacity-40"
24
+ :class="[
25
+ isOpen ? 'mdi-menu-up' : 'mdi-menu-down',
26
+ props.theme === 'dark' ? 'text-white' : 'text-black',
27
+ ]"
28
+ />
29
+ </div>
30
+ <transition name="bluevue-expand">
31
+ <div
32
+ v-show="isOpen"
33
+ class="px-13 my-6 pb-2"
34
+ :class="props.theme === 'dark' ? 'border-[#555555]' : 'border-[#dddddd]'"
35
+ >
36
+ <slot />
37
+ </div>
38
+ </transition>
39
+ </div>
40
+ </template>
41
+
42
+ <script setup lang="ts">
43
+ import { ref, watch } from 'vue'
44
+
45
+ const props = defineProps<{
46
+ /** Panel title */
47
+ title: string
48
+ /** Initial open state */
49
+ expanded?: boolean
50
+ /** 'light' or 'dark' theme */
51
+ theme?: 'light' | 'dark'
52
+ }>()
53
+
54
+ const emit = defineEmits<{
55
+ (e: 'update:expanded', value: boolean): void
56
+ }>()
57
+
58
+ const isOpen = ref(props.expanded ?? true)
59
+
60
+ const togglePanel = (): void => {
61
+ isOpen.value = !isOpen.value
62
+ emit('update:expanded', isOpen.value)
63
+ }
64
+
65
+ watch(
66
+ () => props.expanded,
67
+ (val) => {
68
+ if (val !== undefined) isOpen.value = val
69
+ },
70
+ { immediate: true }
71
+ )
72
+ </script>