Jenkins Active Choice HTML parameter not updating hidden value field with dynamic JS in Groovy script

Description: I’m using the Jenkins Active Choices Plugin to build a dynamic UI with parameters for test suites and their arguments.
I have two parameters:

  1. SUITES (Active Choice Checkbox): Lets the user select one or more test suites from a list, populated by parsing the contents of a
    file.
  2. SUITES_ARGUMENTS (Active Choice HTML): For each selected suite, shows argument textboxes. These are dynamically created via Groovy.
    I want the values entered in the textboxes to be serialized (as
    “Suite:args;Suite2:args2″) and stored in the hidden parameter field
    (input[name=”value”]) so Jenkins can consume it in the pipeline.

I inject JavaScript in the HTML that listens for input changes and updates the hidden field.
However, the hidden field never updates as expected. It either remains blank, gets the wrong value, or the JS doesn’t execute at all.

My Groovy code for the parameters is:

activeChoice(
    choiceType: 'PT_CHECKBOX',
    filterLength: 1,
    filterable: false,
    name: 'SUITES',
    description: 'Test suite to execute.',
    script: groovyScript(
        script: [
            sandbox: true,
            script: """
                def procedures = 'cat /var/lib/jenkins/workspace/Atf_Tests_AAIO/procedures'.execute()
                def procedures_names = procedures.text.split('\\n').collect { line ->
                    // Split at " - Arguments" and take the first part (the test name)
                    line.split(' - Arguments')[0].trim()
                }.sort()
                return procedures_names
            """
        ]
    )
),
activeChoiceHtml(
    choiceType: 'ET_FORMATTED_HTML',
    name: 'SUITES_ARGUMENTS',
    description: 'Arguments for selected test suites',
    referencedParameters: 'SUITES',
    omitValueField: false,
    script: groovyScript(
        script: [
            sandbox: true,
            script: '''
                def selectedSuits = SUITES instanceof List ? SUITES : (SUITES ? SUITES.tokenize(",")*.trim() : [])
                def procedures = 'cat /var/lib/jenkins/workspace/Atf_Tests_AAIO/procedures'.execute()
                def procedures_names = procedures.text.readLines().findAll{ it?.trim() }.sort()

                def html = []
                html << "<div><b>Provide arguments for each selected suite that requires them:</b></div>"
                html << "<div><small>Leave empty to use default.</small></div>"

                selectedSuits.each { s ->
                    // find the line that starts exactly with the suite name
                    def line = procedures_names.find { it.trim().startsWith(s) }
                    if (line) {
                        def parts = line.split(' - Arguments: ', 2)
                        def defaultArgs = parts.size() > 1 ? parts[1].trim() : ''
                        if (defaultArgs) {
                            def argList = defaultArgs.split(',').collect { it.trim() }
                            def safeId = s.replaceAll(/[^A-Za-z0-9_\-]/, "_")
                            def suiteName = parts[0].trim()

                            html << "<div style='margin-top:6px'><strong>${suiteName} - Arguments: ${defaultArgs}</strong></div>"

                            argList.eachWithIndex { arg, idx ->
                                html << """<div style='margin-bottom:4px'>
                                        <label for='${safeId}_arg_${idx}' style='display:inline-block; width:150px;'>${arg}:</label>
                                        <input type='text' class='suite-arg' name='${suiteName}' 
                                            data-arg-idx='${idx}' placeholder='${arg}' style='width:400px; margin-bottom:2px;' /><br/>
                                        </div>"""
                            }
                        }
                    }
                }

                // JS: serialize as "Suite:args;Suite2:args2"
                html << """<script>
                (function() {
                    function updateValue() {
                        var suites = {};
                        document.querySelectorAll('.suite-arg').forEach(function(inp) {
                            var suite = (inp.getAttribute('name') || '').trim();
                            if (!suite) return;
                            var argName = inp.getAttribute('placeholder') || 'ARG';
                            var val = inp.value.trim();
                            if (!suites[suite]) suites[suite] = [];
                            suites[suite].push("-a " + argName + "=" + val);
                        });

                        var hidden = document.querySelector('input[name="value"]');
                        if (hidden) hidden.value = Object.keys(suites).map(function(suite) {
                            return suite + ":" + suites[suite].join(' ');
                        }).join(';');
                    }

                    document.querySelectorAll('.suite-arg').forEach(function(inp) {
                        inp.addEventListener('input', updateValue);
                    });
                    updateValue();
                })();
                </script>"""

                return html.join("\n")
            '''
        ]
    )
),

Problems:

  • The hidden field (input[name=”value”]) does not update when arguments are entered.
  • The JavaScript seems not to execute at all, or runs too early, or
    Jenkins does not allow script execution in this context.

Questions:

  • Is there a reliable way to have Jenkins execute custom JS in Active
    Choice HTML parameters?
  • Is there a better way to serialize and pass dynamic argument values
    to the pipeline?
  • What am I doing wrong with the plugin, or is this a limitation of
    Jenkins/Uno-Choice? Any best practices for working around this issue?

Images of the Jenkins UI:

Two SUITS selected
The script does not appear

Cybersource risk API fails with error “Authentication Failed”

I am using a javascript call through insomnia (like postman) to do a POST call to https://apitest.cybersource.com/risk/v1/decisions. Ref doc: Cybersource

const crypto = require('crypto-js');
const merchantId = insomnia.environment.get('MERCHANT_ID');
const merchantKeyId = insomnia.environment.get('VISA_KEY');
const merchantSecretKey = insomnia.environment.get('VISA_SECRET');
const requestHost = 'apitest.cybersource.com';
const requestMethod = '/risk/v1/decisions';

// Request body
const requestBody = insomnia.request.body;

// Digest
const digest = `SHA-256=${crypto.enc.Base64.stringify(crypto.SHA256(crypto.enc.Utf8.parse(requestBody)))}`;
insomnia.environment.set("bodyDigest",digest);

// Date
// const date = new Date(Date.now()).toUTCString();
var date = 'Fri, 12 Sep 2025 17:29:42 GMT';
insomnia.environment.set("date", date);

// Signature
const string = `host: ${requestHost}ndate: ${date}nrequest-target: ${requestMethod}ndigest: ${digest}nv-c-merchant-id: ${merchantId}`;
const signature = `keyid="${merchantKeyId}", algorithm="HmacSHA256", headers="host date (request-target) digest v-c-merchant-id", signature="${crypto.enc.Base64.stringify(crypto.HmacSHA256(crypto.enc.Utf8.parse(string), crypto.enc.Base64.parse(merchantSecretKey)))}"`;
insomnia.environment.set("signature", signature);

I have the following headers set as well as per cybersource documentation:

Content-Type: application/json
digest: SHA-256={{ _.bodyDigest }}
signature: {{ _.signature }}
v-c-date: {{ _.date }}
v-c-merchant-id: {{ _.MERCHANT_ID }}
Accept: application/json

But for some reason I still get the following response from cybersource:

{
    "response": {
        "rmsg": "Authentication Failed"
    }
}

Few things I tried to make it work for cybersource:

  1. I see the documentation says the header field as date but when I intercepted the call made from the live terminal, I see the header field is v-c-date. Does this make a difference? I tried both.
  2. I tried to retrace the python sdk to see if the script I use is any different but I can’t find any differences: https://github.com/CyberSource/cybersource-rest-client-python/blob/master/authenticationsdk/http/GetSignatureParameter.py#L33
  3. I used the sandbox to verify my credentials and they work in live terminal of sandbox.

Why the signature generated through the above code is different from the one in live terminal (which works)? Am I missing some data when generating the signature?

How do I predict, how window.print() will put html on a page? [closed]

I cannot figure out how my div is being translated into 8.5×11 page, by window.print(). Changing the dimensions of the print-element seems to make no difference; window.print() picked a scale and making my div wider or thinner doesn’t change it. On top of that, different pages seem to have different scales; despite having similar widths.

Things that might be helpful:

  1. My site is SharePoint under the hood; in case that is helpful.

  2. One element – width: 1101px; height:1508px gets printed on 1 page.

  3. Another element – width: 2682.5px; height: 1086px is 1 page.

  4. Helpful fact 2 and 3 have the correct widths and heights. They are both portrait; even though fact 3 looks like it should be landscape.

    My ultimate goal is to predict when my element is going over 11 inches, on a piece of paper. Auto and avoid, for break-before, break-inside and break-after, still have bizarre page breaks.

My plan is to force new pages, where I think they should be. However, I can’t do that if I don’t have a relationship between the height of my print-element and the piece of paper I want to print it on.

Buttons are flying in all directions whith motion

I have a project using react and motion.

Currently i have a component with a fixed overlay showing a bunch of ui. This UI lets the user toggle between 2 views, one vertical and one horizontal.

What’s happening:

  • When the view is toggled various parts of the overlay fly into view from the top or bottom of the screen. This happens because the page changes hight drasticly.

What do i want to happen:

  • The idea was that when changing views, the UI would stay still, fixed over the rest of the page.

I could just take out all layout animations from all motion components, but that would make the UI quite boring and it’s not my intent. I want to keep all the diferent animations but just confine them to the overlay.

I’ve tried using layoutRoot but it’s not really doing much.

Here’s a rundown of the components:

const { setComic, comic, layout, modal } = useComicReaderContext();
useEffect(() => {
    setComic(currentComic);
});
return (
    <div className="flex h-dvh w-full justify-center">
    <AnimatePresence
    initial={false}
    mode="sync"
    >
        {layout === comicLayoutModes.VERTICAL && (
            <VerticalLayout
            key={'vertical'}
            pages={currentComic.pages} //renders a bunch of images one under the other
                    />
        )}
        {layout === comicLayoutModes.SINGLE_PAGE && (
            <SinglePageLayout key={'singlePage'} /> // renders 1 image at a time.
        )}
        {modal && (
            <ComicInterface
            comic={currentComic}
            key={'UIOverlay'}
            />
            )}
        </AnimatePresence>
    </div>

and the interface itself:

const { title, author, tags, likes, price } = comic;
const { setModal, setDrawer, drawer } = useComicReaderContext();


return (
    <motion.div
    ref={overlay}
    layoutRoot
    key={'comicInterfaceOverlay'}
    className="fixed bottom-0 left-0 right-0 top-0 z-10 w-full overflow-hidden bg-black/75"
    >
        <motion.div className="mx-auto flex h-full w-full justify-between gap-2 py-2 text-white md:py-8">
            <AnimatePresence mode="sync">
                <motion.div
                transition={{ ease: 'easeInOut' }}
                        key="left col"      
                        className="flex shrink-0 flex-col justify-between pl-2 md:pl-8"
            >
                {`some buttons`}
            </motion.div>

{/* center col THISONE goes nuts when changing view*/} 
            <motion.div
            key={'centerCol'}
            onClick={(e) => onDismiss(e)}
            transition={{ ease: 'easeInOut' }}
            className="flex h-full w-full shrink flex-col items-center justify-center md:w-8/12"
            >
                    <motion.button
                initial={{ scale: 1 }}
                layout
                whileHover={{ scale: 1.05 }}
                whileTap={{ scale: 0.95 }}
                onClick={(e) => onDismiss(e)}
                className="cursor-pointer inline-flex h-20 w-[150px] items-center justify-center rounded-3xl bg-primary p-2 text-sm text-black hover:shadow-[0_0_10px_1px_rgba(250,250,250,1)] md:w-[250px] md:p-4 md:text-lg"
                >
                    Click to continue reading 
                </motion.button>
                </motion.div>
{/* right col */}
                <motion.div
                key="rightCol"
                layout
                transition={{ duration: 0.2 }}
                className={`flex flex-col justify-center gap-y-12 justify-self-end pr-2 md:pr-8`}
                >
                        <div 
                                        className="flex flex-col items-center"
                                        >
                    <div className='flex flex-col items-center w-[80px]'>
                                    <button
                        onClick={() => handleToggle()}
                        className="border-gray rounded-full w-[50px] h-[30px] p-1 border-2 bg-body cursor-pointer flex items-center" 
                        >
                                            {layout === comicLayoutModes.VERTICAL && <motion.div
                                                layout="position"
                                                layoutId='knob'
                                                layoutDependency={[layout, drawer]}
                                                className={`flex items-center justify-center rounded-full bg-primary w-[20px] h-[20px] ml-auto`}
                                                >
                                                    <GalleryVertical size={12} className='stroke-body' />
                                                </motion.div>}
                                            {layout === comicLayoutModes.SINGLE_PAGE && <motion.div
                                                layoutId='knob'
                                                layout="position"
                                                layoutDependency={[layout, drawer]}
                                                className={`flex items-center justify-center rounded-full bg-primary w-[20px] h-[20px] mr-auto`}
                                                >
                                                    <GalleryHorizontal size={12} className='stroke-body' />
                                                </motion.div>}
                                        </button>
                                        <span className='text-sm'>

                                        {layout === comicLayoutModes.VERTICAL ? "Vertical" : "Single Page"}
                                        </span>
                                    </div>


                        </div>
                    </motion.div>
                    {drawer && <Drawers open={drawer} />}
                </AnimatePresence>
            </motion.div>
        </motion.div>
    );
};

Scrolling & Map generation issue

i’m working on a client’s real estate site and it has this layout where i have a list of properties on left side and a map on right side. The map shows markers of prices on the respective property’s exact location(i have latitudes and longitudes stored in data) and whenever i hover on any property the map gets zoomed in to that respective location. On a single page we show 8 listings , the problem occurring is that whenever i scroll the list rapidly , the scrolling feels choppy , the map lags and the movement from one marker to another feels choppy as well which is spoiling user experience.

Please i need some help with this as this has been a recurring issue.

Tech stack used for client side: Astro react(jsx).

Need help and suggestions or references to solve this issue.

i have tried generating the markers and map once and just moving the map whenever a property is hovered but still feels choppy , used AI tools for help too but nothing works.

I’m expecting the list to scroll smoothly along with map generation to render smoothly even if someone scrolls rapidly through the list

If statements using other script elements functions

Somewhat a follow up to my previous question but, I’ve gotten the functions to work properly, and I have two console.log() statements in the secondary script element to test it, and it works. However, when I attempt to use this code:

<script src="https://player.twitch.tv/js/embed/v1.js"></script>
    <div id="twitchPlayer"></div>
    <script type="text/javascript">
      if(getLive() == false){
        var options = {
          width:800,
          height:450,
          channel:"rushdownresort",
          parent:["127.0.0.1"]
        }
        var player = new Twitch.Player("twitchPlayer", options);
      }
      console.log(getLive())
      console.log(getVideos())
    </script>

The embed doesn’t show until I change the comparison to !=, which is actually false, due to the channel only being live on sundays. Clearly the function isn’t returning something that works properly for a comparison in another script element, despite working within its original element.
Is this a scope issue?
By the way the end goal of this code is to display the livestream when the channel is live, and display the latest VOD when the channel is offline

Access the input element that dynamically generated either using its id or templatereference

I have to add and remove the product items by getting either the id of input element or through template reference of the input element. Since i need some other activities by accessing the input element. Please avoid adding new property in input productlists array.
Below mentioned the output

My output page

my .ts file

export class ProductsComponent implements OnInit {
  @ViewChildren('quantityreference') dynamicElements!: QueryList<ElementRef>;
  productlists = JSON.parse(`[
    {
        "productId": "T00110",
        "productName": "first",
        "productPrice": "0",
        "gst":"20"
    },
    {
      "productId": "T000",
      "productName": "Punnakuuu",
      "productPrice": "40",
      "gst":"20"
  },
    {
        "productId": "T1111",
        "productName": "Thenkaai Punnaku",
        "productPrice": "40",
        "gst":"18"
    },
    {
        "productId": "MT1",
        "productName": "Mattu Theevanam",
        "productPrice": "55",
        "gst":"18"
    },
    {
        "productId": "CP1",
        "productName": "m Punnaku",
        "productPrice": "55",
        "gst":"12"
    },
    {
      "productId": "CP2",
      "productName": "ell Punnaku",
      "productPrice": "22",
      "gst":"12"
  }]`
  );

  constructor() { }
  purchasedProudct = new Purchasedproduct("", "", 0, 0, "");
  selectedquantity: number = 0;
  @ViewChildren('quantityreference', { read: ElementRef }) products!: QueryList<ElementRef<HTMLElement>>;
  ngOnInit(): void {
  }
  increment(indexvalue: number) {
    const item = this.productlists[indexvalue];
    this.selectedquantity++;
  }
  decrement(indexvalue: number) {
    const item = this.productlists[indexvalue];
    if (this.selectedquantity > 0) {
      this.selectedquantity--;
    }
  }
}

my .html file

<ng-container *ngFor="let product of productlists; let i=index">
    <div class="products" *ngIf="product.productPrice > 0">
<h4>{{product.productName}}</h4>
<p>Rs. {{product.productPrice}}</p>
<button mat-icon-button (click)="decrement(i)" color="accent" #buttondecreament>
    <mat-icon>remove</mat-icon>
  </button>
  <mat-form-field  style="width: 50px;">
    <input matInput [(ngModel)]="selectedquantity" size="2" [id]="'quantity_input'+i" #quantityreference>
  </mat-form-field>
  <button mat-icon-button (click)="increment(i)" color="accent" #buttonincreament>
    <mat-icon>add</mat-icon>
  </button>
</div>
</ng-container>

Anyone try to solve this.

Convert .TSV to CSV, JSON or XML

On N8N, I am downloading a .TSV file from Amazon but for N8N to loop through the data, I need to convert it to an better format for looping (unless I am mistaken).

.CSV, .XML, .JSON would likely be suitable to use a loop node on.

If I am to use a code node in N8N for this, then I need it to be using JavaScript to convert.

This is the JS I used in a code node as an attempt:

const tsvToCsv = (tsvString) => {
  if (!tsvString || typeof tsvString !== 'string') {
    return '';
  }
  const lines = tsvString.split('n');
  const csvLines = lines.map(line => {
    const values = line.split('t');
    const csvValues = values.map(value => {
      // Handle values with special characters that need to be quoted
      if (value.includes(',') || value.includes('"') || value.includes('n')) {
        const escapedValue = value.replace(/"/g, '""');
        return `"${escapedValue}"`;
      }
      return value;
    });
    return csvValues.join(',');
  });
  return csvLines.join('n');
};

// Access the data directly from the first item of the previous node.
// This is where the file content is stored.
const tsvData = items[0].data;

// Convert the TSV data to CSV
const csvData = tsvToCsv(tsvData);

// Set the output for the next node in the workflow
return [{
  json: {
    csvData: csvData
  }
}];

This is the most I got from the tested code:
enter image description here

Why some changes were done in a file when file pushed into the github and what was the solution for it? [closed]

I have been working on a quiz project.There i was getting a problem like changes were done without being explicitly by me and again the right code then also i was appearing like before.So,i need a solution from an expert to overcome the situation.

I tried to push the code right code to the github and some data in the files were changing implicitly so iam expecting the right code which is in my local storage to be pushed into the github.

JS map function in Astro that should work but doesn’t

I have a component for a card with a couple of properties that all work fine one of the properties is a call to a database that fetches some links.

Every card has either none or a few links.
So I am using the card component like this:

{
  laureates.map((item) => (
    <PeopleCard
      title={item.laureates?.title}
      content={item.content}
      links={item.laureates?.links}
     />
  ))
}

And inside the PeopleCard component i have the card itself with {title} and {card}, and then I want to map over the links since there can be a few so that looks like this:

<ul>
  {
    links?.map((item) => (
      <li>
        <a href={ item?.attachment.attached === 'file' ? item.attachment.file.node.mediaItemUrl : item.attachment.url }>{item.text}</a>
      </li>
     ))
   }
</ul>

But that doesn’t work and I get an error saying “item is not defined”.
But if I do like this:

<ul>
  {
    links?.map((item) => (
      <li>
        <a href={ item?.attachment.attached === 'file' ? item.attachment.file.node.mediaItemUrl : item.attachment.url }>Just some text</a>
      </li>
     ))
   }
</ul>

or like this:

<ul>
  {
    links?.map((item) => (
      <li>
        <a href="https://google.com">{item.text}</a>
      </li>
     ))
   }
</ul>

Both of those works as expected and returns what I’m looking for, it’s only when I combine them all goes to hell and I can’t figure out why!
What am I missing?

Also my fetch query looks like this:

query getLaureates {
  allLaureates(first: 100) {
    nodes {
      title
      content
      laureates {
        links {
          attachment {
            attached
            url
            file {
              node {
                mediaItemUrl
              }
            }
          }
          text
        }
      }
    }
  }
}

The Intersection Observer callback is being called repeatedly

import { useEffect, useRef, useState } from "react";

const HEADER_HEIGHT = 64;
const BREADCRUMBS_HEIGHT = 61;
const OFFSET = 0;

function App() {
  const stickyRef = useRef(null);
  const [isStuck, setIsStuck] = useState(false);

  useEffect(() => {
    const stickyElement = stickyRef.current as unknown as HTMLDivElement;
    if (!stickyElement) return;

    const sentinel = document.createElement("div");
    sentinel.style.height = "1px";
    sentinel.style.position = "absolute";
    sentinel.style.top = `${HEADER_HEIGHT + BREADCRUMBS_HEIGHT - OFFSET}px`;
    sentinel.style.left = "0";
    sentinel.style.right = "0";
    sentinel.style.pointerEvents = "none";
    sentinel.style.backgroundColor = "red";
    sentinel.style.border = "1px dashed red";
    sentinel.style.zIndex = "1";

    stickyElement.parentNode?.insertBefore(sentinel, stickyElement);

    const observer = new IntersectionObserver(
      ([entry]) => {
        setIsStuck(!entry.isIntersecting);
      },
      {
        root: null,
        rootMargin: "0px",
        threshold: 0,
      }
    );

    observer.observe(sentinel);

    return () => {
      observer.disconnect();
      if (sentinel.parentNode) {
        sentinel.parentNode.removeChild(sentinel);
      }
    };
  }, []);

  return (
    <>
      <div
        style={{
          height: HEADER_HEIGHT,
          backgroundColor: "lightgreen",
          color: "#000000bd",
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
        }}
      >
        Header
      </div>
      <div
        style={{
          height: BREADCRUMBS_HEIGHT,
          backgroundColor: "lightpink",
          color: "#000000bd",
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
        }}
      >
        Navbar
      </div>
      <div
        ref={stickyRef}
        style={{
          backgroundColor: "lightgray",
          height: isStuck ? 60 : 300,
          position: "sticky",
          top: 0,
          transition: "height 0.3s ease",
          color: "#000000bd",
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
        }}
      >
        Sticky
      </div>
      <p style={{ margin: 0, padding: 16 }}>
        Lorem, ipsum dolor sit amet consectetur adipisicing elit. Ratione
        ducimus nam a id ipsam, eum nihil minus ab dolorem exercitationem,
        praesentium tempora pariatur ullam? Asperiores optio eos consequuntur
        temporibus omnis, incidunt quia aspernatur autem mollitia. Alias
        distinctio minima, quos repellat ipsa nesciunt quisquam amet cupiditate
        perspiciatis sit optio reprehenderit esse, porro explicabo. Fuga iure,
        iste doloribus corrupti pariatur accusamus, quia aspernatur quibusdam
        facilis deserunt qui debitis accusantium consequuntur! Iusto repellendus
        rem sint voluptatibus ipsam itaque deleniti mollitia repellat ratione
        recusandae! Veritatis placeat soluta odio nihil, aliquid dolor iste
        dolorem facilis laudantium id tempora nostrum, ducimus possimus
        recusandae dicta porro enim sed sapiente explicabo incidunt repudiandae
        modi. Distinctio explicabo id, repudiandae saepe totam eligendi facere
        cum repellat voluptates aliquid adipisci quod ipsam ipsa dicta expedita
        dolor non aperiam accusamus consequuntur, maiores dolores fugit? Nam
        earum sapiente debitis! Odio exercitationem placeat iusto, nihil magnam,
        accusamus itaque nam amet culpa distinctio aliquam quis expedita
        suscipit eligendi temporibus ea aut veniam quia, ab eum labore corrupti
        cupiditate ipsa!
      </p>
    </>
  );
}

export default App;

In the above code I want to collapse the sticky section when it is stuck to the top of the viewport. To do that I used the IntersectionObserver browser API.

In your browser, open responsive mode, select iPhone SE (375px * 667px). Then if you scroll down you will see the multiple collapsing and expanding of the sticky section!

I attempted to set a guard for setIsStuck based on the height of the p tag. It works, but I don’t like this solution.
I want a clean solution that doesn’t depend on p tag section.

CodeSandbox Link

How to rotate a webpage 90°? [duplicate]

I would like to make a website display in the same way it would if the user rotated their monitor at the OS level.

The easiest way to do that (if it were supported) would be to change the coordinate system of the webpage. Any JS on the page that measures top would get shadowed to measure the physical right instead, measuring right should measure bottom, etc. Any CSS that places an element with a top value would be placing its physical right.

I would like to rotate an existing webpage 90°, while having to change as little of the existing code as possible.

I tried

:root {
    transform: rotate(90deg);
    origin: top left;
    right: 0;
    top: 0;
}

But it normally just screws up all of the rendering and JS of the site.

What could I write in the dev console on this stackoverflow webpage to get it to display as if I used my OS to rotate my monitor 90°?

Why does my code result in a massive unexpected energy loss in my collision simulation when the equation appears correct?

I made some JS code to simulate the collision between two objects in a frictionless, dragless, and perfectly elastic world. I designed it so momentum is perfectly conserved, or so I thought, as I tested it, and there was a massive energy loss.

The first cube would move at a speed of -20, and collide with the second stationary cube. the cubes have equal mass. The speeds for both cubes are way less after the collision, with the first cube somehow retaining some of its own speed with a speed of -0.661 instead of 0, while the second cube, instead of having a speed of exactly -20, has a speed of -3.63, instead.

The directions are correct (ignoring the fact that the cubes keep some of their speed), it’s just the total momentum has a large portion lost with every collision. There are no issues with the wall collisions though.

Here is the code:

var canvas = document.getElementById('PhysicsSim');
var con = canvas.getContext('2d');
var speedC1 = -20 //speed for big cube
var speedC2 = 0 // speed for small cube
var simOn = "false"
let Mass1
let Mass2
var Bounce = 0
var MassSum = Mass1 + Mass2

document.getElementById('StartButton').onclick = function(){
    simOn = "true"
}

document.getElementById('StopButton').onclick = function(){
    simOn = "false"
}

document.getElementById('SubmitUnit').onclick = function(){
    Mass1 = document.getElementById('BigInput').value;
    Mass2 = document.getElementById('SmallInput').value;
    console.log(Mass1);
    console.log(Mass2);
    console.log(speedC2);
    console.log(speedC1);
    MassSum = Mass1 + Mass2
}

X1 = 150
X2 = 120



con.fillRect(0, 140, 300, 10);
con.fillRect(0, 0, 10, 140);


setInterval(() => {
    if (simOn == "true") {
        if ((X2 += speedC2*0.005) <= 10) {
            X2 = 10
            speedC2 = speedC2*-1
            Bounce += 1
        } else if (X1 <= X2 + 10) {
            X2 = X1 - 10
            speedC2 = ((2*Mass1)/MassSum)*speedC1 + ((Mass2-Mass1)/MassSum)*speedC2
            speedC1 = ((Mass1 - Mass2)/MassSum)*speedC1 + ((2*Mass2)/MassSum)*speedC2
            Bounce += 1
            console.log(speedC2);
            console.log(speedC1);
            console.log(Bounce);
            //put the collision logic for dual cubes here
        } else {
            X2 += speedC2*0.005
            X1 += speedC1*0.005
        }
    }
}, 5);

setInterval(() => {
    if (simOn == "true") {
    con.clearRect(0, 0, canvas.width, canvas.height);
    con.fillRect(0, 140, 300, 10);
    con.fillRect(0, 0, 10, 140);
    con.fillRect(X1, 120, 20, 20);
    con.fillRect(X2, 130, 10, 10);
    }
}, 50);
h1{
  font-size:48pt;
  font-family:Helvetica
}

.c{
  text-align:center;
}

canvas {
    border: 3px solid black;
    background: white;
    width: 80%;
    display: block;
    margin-left: auto;
    margin-right: auto;
}
<canvas id="PhysicsSim"></canvas>

<label><br>Big Cube Mass: </label>
<input id="BigInput">
<label><br>Small Cube Mass: </label>
<input id="SmallInput"><br>
<button id="SubmitUnit">Submit</button><br><br>
<button id="StartButton">Start Simulation</button><br>
<button id="StopButton">Stop Simulation</button>

I already tried flipping it, and solving for the equation gives the right answer seemingly. I’m pretty sure the issue is in the logic, not anywhere else.

Image of simulation