hunk.code_window: 	return isAdmin, nil
   }
   // GetStackFilePaths returns a list of file paths based on stack project path
   func GetStackFilePaths(stack *portainer.Stack, absolute bool) []string {
   	if !absolute {
   		return append([]string{stack.EntryPoint}, stack.AdditionalFiles...)
   	}
  
hunk.labels: keep keep keep add keep keep keep keep
hunk.after_edit: // If absolute is false, the path sanitization step will be skipped, which makes the returning
   // paths vulnerable to path traversal attacks. Thus, the followed function using the returning
   // paths are responsible to sanitize the raw paths
   // If absolute is true, the raw paths will be sanitized
  
hunk.file_path: api/stacks/stackutils/util.go
hunk.type: add
file: import { useState } from 'react';
  import { Info } from 'lucide-react';
  
  import { getAgentShortVersion } from '@/portainer/views/endpoints/helpers';
  import { useAgentDetails } from '@/react/portainer/environments/queries/useAgentDetails';
  
  import { CopyButton } from '@@/buttons/CopyButton';
  import { Code } from '@@/Code';
  import { FormSectionTitle } from '@@/form-components/FormSectionTitle';
  import { NavTabs } from '@@/NavTabs';
  import { Icon } from '@@/Icon';
  
  const deployments = [
    {
      id: 'k8sLoadBalancer',
      label: 'Kubernetes via load balancer',
      command: kubeLoadBalancerCommand,
      showAgentSecretMessage: true,
    },
    {
      id: 'k8sNodePort',
      label: 'Kubernetes via node port',
      command: kubeNodePortCommand,
      showAgentSecretMessage: true,
    },
  ];
  
  export function DeploymentScripts() {
    const [deployType, setDeployType] = useState(deployments[0].id);
  
    const agentDetailsQuery = useAgentDetails();
  
    if (!agentDetailsQuery) {
      return null;
    }
  
    const { agentVersion, agentSecret } = agentDetailsQuery;
  
    const options = deployments.map((c) => {
      const code = c.command(agentVersion);
  
      return {
        id: c.id,
        label: c.label,
        children: (
          <DeployCode
            agentSecret={agentSecret}
            showAgentSecretMessage={c.showAgentSecretMessage}
            code={code}
          />
        ),
      };
    });
  
    return (
      <>
        <FormSectionTitle>Information</FormSectionTitle>
  
        <div className="form-group">
          <span className="col-sm-12 text-muted small">
            Ensure that you have deployed the Portainer agent in your cluster
            first. Refer to the platform related command below to deploy it.
          </span>
        </div>
  
        <NavTabs
          options={options}
          onSelect={(id: string) => setDeployType(id)}
          selectedId={deployType}
        />
      </>
    );
  }
  
  function kubeNodePortCommand(agentVersion: string) {
    const agentShortVersion = getAgentShortVersion(agentVersion);
  
    return `kubectl apply -f https://downloads.portainer.io/ce${agentShortVersion}/portainer-agent-k8s-nodeport.yaml`;
  }
  
  function kubeLoadBalancerCommand(agentVersion: string) {
    const agentShortVersion = getAgentShortVersion(agentVersion);
  
    return `kubectl apply -f https://downloads.portainer.io/ce${agentShortVersion}/portainer-agent-k8s-lb.yaml`;
  }
  
  interface LoadBalancerProps {
    agentSecret?: string;
    showAgentSecretMessage?: boolean;
    code: string;
  }
  
  function DeployCode({
    agentSecret,
    showAgentSecretMessage,
    code,
  }: LoadBalancerProps) {
    return (
      <>
        {showAgentSecretMessage && agentSecret && (
          <p className="text-muted small my-6">
            <Icon icon={Info} mode="primary" className="mr-1" />
            Note that the environment variable AGENT_SECRET will need to be set to
            <code>{agentSecret}</code>. Please update the manifest that will be
            downloaded from the following script.
          </p>
        )}
        <Code>{code}</Code>
        <div className="mt-2">
          <CopyButton copyText={code}>Copy command</CopyButton>
        </div>
      </>
    );
  }
  