var/cache/dev/twig/ce/ce33f1a336b501ccf515e493a104daa7fd455b12fbf3de30504bd569466a894b.php line 40

Open in your IDE?
  1. <?php
  2. use Twig\Environment;
  3. use Twig\Error\LoaderError;
  4. use Twig\Error\RuntimeError;
  5. use Twig\Extension\SandboxExtension;
  6. use Twig\Markup;
  7. use Twig\Sandbox\SecurityError;
  8. use Twig\Sandbox\SecurityNotAllowedTagError;
  9. use Twig\Sandbox\SecurityNotAllowedFilterError;
  10. use Twig\Sandbox\SecurityNotAllowedFunctionError;
  11. use Twig\Source;
  12. use Twig\Template;
  13. /* Product/detail.twig */
  14. class __TwigTemplate_da5ad31feda8695d41b76c2e300641cf69fccce492d7fb053b687f2a0b3adb3c extends \Eccube\Twig\Template
  15. {
  16.     private $source;
  17.     private $macros = [];
  18.     public function __construct(Environment $env)
  19.     {
  20.         parent::__construct($env);
  21.         $this->source $this->getSourceContext();
  22.         $this->blocks = [
  23.             'stylesheet' => [$this'block_stylesheet'],
  24.             'javascript' => [$this'block_javascript'],
  25.             'main' => [$this'block_main'],
  26.         ];
  27.     }
  28.     protected function doGetParent(array $context)
  29.     {
  30.         // line 11
  31.         return "default_frame.twig";
  32.     }
  33.     protected function doDisplay(array $context, array $blocks = [])
  34.     {
  35.         $macros $this->macros;
  36.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  37.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->enter($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "template""Product/detail.twig"));
  38.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02 $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  39.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->enter($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "template""Product/detail.twig"));
  40.         // line 13
  41.         $context["body_class"] = "product_page";
  42.         // line 11
  43.         $this->parent $this->loadTemplate("default_frame.twig""Product/detail.twig"11);
  44.         $this->parent->display($contextarray_merge($this->blocks$blocks));
  45.         
  46.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->leave($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof);
  47.         
  48.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->leave($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof);
  49.     }
  50.     // line 15
  51.     public function block_stylesheet($context, array $blocks = [])
  52.     {
  53.         $macros $this->macros;
  54.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  55.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->enter($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""stylesheet"));
  56.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02 $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  57.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->enter($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""stylesheet"));
  58.         // line 16
  59.         echo "    <style>
  60.         .slick-slider {
  61.             margin-bottom: 10px;
  62. \t\t\tmargin-top: -20px;
  63.         }
  64.         .slick-dots {
  65.             position: absolute;
  66.             bottom: -45px;
  67.             display: block;
  68.             width: 100%;
  69.             padding: 0;
  70.             list-style: none;
  71.             text-align: center;
  72.         }
  73.         .slick-dots li {
  74.             position: relative;
  75.             display: inline-block;
  76.             width: 20px;
  77.             height: 20px;
  78.             margin: 0 5px;
  79.             padding: 0;
  80.             cursor: pointer;
  81.         }
  82.         .slick-dots li button {
  83.             font-size: 0;
  84.             line-height: 0;
  85.             display: block;
  86.             width: 20px;
  87.             height: 20px;
  88.             padding: 5px;
  89.             cursor: pointer;
  90.             color: transparent;
  91.             border: 0;
  92.             outline: none;
  93.             background: transparent;
  94.         }
  95.         .slick-dots li button:hover,
  96.         .slick-dots li button:focus {
  97.             outline: none;
  98.         }
  99.         .slick-dots li button:hover:before,
  100.         .slick-dots li button:focus:before {
  101.             opacity: 1;
  102.         }
  103.         .slick-dots li button:before {
  104.             content: \" \";
  105.             line-height: 20px;
  106.             position: absolute;
  107.             top: 0;
  108.             left: 0;
  109.             width: 12px;
  110.             height: 12px;
  111.             text-align: center;
  112.             opacity: .25;
  113.             background-color: black;
  114.             border-radius: 50%;
  115.         }
  116.         .slick-dots li.slick-active button:before {
  117.             opacity: .75;
  118.             background-color: black;
  119.         }
  120.         .slick-dots li button.thumbnail img {
  121.             width: 0;
  122.             height: 0;
  123.         }
  124.     </style>
  125.     <link rel=\"stylesheet\" href=\"/html/user_data/js/style.css\">
  126.     <link rel=\"stylesheet\" href=\"/html/plugins/icheck-bootstrap/icheck-bootstrap.min.css\">
  127.     <style>
  128.         /* Show zoom cursor on product images to hint click-to-expand */
  129.         .item_visual .slide-item a { display: block; cursor: zoom-in; }
  130.     </style>
  131.     <style>
  132.         /* ============================================
  133.            商品詳細グリッド: 画像50% / 内容50%(均等)
  134.         ============================================ */
  135.         @media (min-width: 768px) {
  136.             body.product_page .ec-grid2 {
  137.                 display: flex;
  138.                 align-items: flex-start;
  139.             }
  140.             body.product_page .ec-grid2 .ec-grid2__cell {
  141.                 width: 50%;
  142.                 flex: 0 0 50%;
  143.                 min-width: 0;
  144.             }
  145.             body.product_page .ec-grid2 .ec-grid2__cell2 {
  146.                 width: 50%;
  147.                 flex: 0 0 50%;
  148.                 min-width: 0;
  149.             }
  150.         }
  151.         /* ============================================
  152.            商品説明欄内のHTMLが画面幅を突き抜けないように
  153.         ============================================ */
  154.         body.product_page .ec-productRole__description {
  155.             min-width: 0;
  156.             overflow-wrap: break-word;
  157.             word-break: break-word;
  158.         }
  159.         body.product_page .ec-productRole__description img,
  160.         body.product_page .ec-productRole__description table,
  161.         body.product_page .ec-productRole__description iframe,
  162.         body.product_page .ec-productRole__description video {
  163.             max-width: 100% !important;
  164.             height: auto;
  165.         }
  166.         body.product_page .ec-productRole__description table {
  167.             display: block;
  168.             overflow-x: auto;
  169.             -webkit-overflow-scrolling: touch;
  170.         }
  171.         /* ============================================
  172.            スマホ用 見積金額 下部固定バー
  173.         ============================================ */
  174.         #sp-mitsumori-bar {
  175.             display: none;
  176.         }
  177.         /* ============================================
  178.            スマホ用 お見積りの詳細 ボトムシート
  179.         ============================================ */
  180.         .sp-detail-sheet { display: none; }
  181.         .sp-detail-sheet.is-open {
  182.             display: block;
  183.             position: fixed;
  184.             top: 0; left: 0; right: 0; bottom: 0;
  185.             z-index: 2000;
  186.         }
  187.         .sp-detail-sheet__overlay {
  188.             position: absolute;
  189.             top: 0; left: 0; right: 0; bottom: 0;
  190.             background: rgba(0,0,0,0.45);
  191.         }
  192.         .sp-detail-sheet__panel {
  193.             position: absolute;
  194.             left: 0; right: 0; bottom: 0;
  195.             background: #fff;
  196.             border-radius: 14px 14px 0 0;
  197.             max-height: 82vh;
  198.             display: flex;
  199.             flex-direction: column;
  200.             box-shadow: 0 -4px 20px rgba(0,0,0,0.25);
  201.             padding-bottom: env(safe-area-inset-bottom);
  202.             animation: spSheetUp 0.22s ease-out;
  203.         }
  204.         @keyframes spSheetUp {
  205.             from { transform: translateY(100%); }
  206.             to   { transform: translateY(0); }
  207.         }
  208.         .sp-detail-sheet__header {
  209.             display: flex;
  210.             align-items: center;
  211.             justify-content: space-between;
  212.             padding: 14px 16px;
  213.             border-bottom: 1px solid #eee;
  214.             flex: 0 0 auto;
  215.         }
  216.         .sp-detail-sheet__title { font-size: 16px; font-weight: bold; color: #333; }
  217.         .sp-detail-sheet__close {
  218.             background: none;
  219.             border: none;
  220.             font-size: 26px;
  221.             line-height: 1;
  222.             color: #888;
  223.             cursor: pointer;
  224.             padding: 0 4px;
  225.         }
  226.         .sp-detail-sheet__body {
  227.             overflow-y: auto;
  228.             -webkit-overflow-scrolling: touch;
  229.             padding: 4px 0;
  230.             flex: 1 1 auto;
  231.         }
  232.         .sp-detail-sheet__body ul { list-style: none; margin: 0; padding: 0; }
  233.         .sp-detail-sheet__body li { border-bottom: 1px solid #f2f2f2; }
  234.         .sp-detail-sheet__body .nav-link {
  235.             display: flex;
  236.             align-items: center;
  237.             justify-content: space-between;
  238.             padding: 12px 16px;
  239.             color: #333;
  240.             font-size: 14px;
  241.         }
  242.         .sp-detail-sheet__body .nav-link .float-right {
  243.             float: none !important;
  244.             font-weight: bold;
  245.             white-space: nowrap;
  246.             margin-left: auto;
  247.         }
  248.         .sp-detail-sheet__footer {
  249.             display: flex;
  250.             gap: 8px;
  251.             padding: 12px 16px 16px;
  252.             border-top: 1px solid #eee;
  253.             flex: 0 0 auto;
  254.         }
  255.         .sp-detail-sheet__footer button {
  256.             flex: 1 1 auto;
  257.             padding: 12px;
  258.             border-radius: 8px;
  259.             font-size: 14px;
  260.             font-weight: bold;
  261.             cursor: pointer;
  262.         }
  263.         .sp-detail-sheet__invoice {
  264.             background: #fff;
  265.             border: 1px solid #17a2b8;
  266.             color: #17a2b8;
  267.         }
  268.         .sp-detail-sheet__cart {
  269.             background: #c00;
  270.             border: 1px solid #c00;
  271.             color: #fff;
  272.         }
  273.         /* ============================================
  274.            商品タイプ選択 共通スタイル
  275.         ============================================ */
  276.         /* セクションラベル */
  277.         .rp-section-label {
  278.             font-size: 14px;
  279.             font-weight: bold;
  280.             color: #333;
  281.             margin-bottom: 10px;
  282.         }
  283.         .rp-section-label span {
  284.             font-weight: normal;
  285.             color: #c00;
  286.         }
  287.         /* ---- 1. 画像付きカード ---- */
  288.         .rp-card-group {
  289.             display: flex;
  290.             flex-wrap: wrap;
  291.             gap: 8px;
  292.             margin-bottom: 4px;
  293.         }
  294.         .rp-card {
  295.             position: relative;
  296.             cursor: pointer;
  297.             touch-action: manipulation; /* drop iOS 300ms tap delay (#15) */
  298.             -webkit-tap-highlight-color: rgba(0,0,0,0);
  299.             /* iOS Safari: prevent the first tap from being consumed as a text
  300.                selection (\"字だけ青くなる\" = selection highlight) which forced a
  301.                2nd tap to actually switch the option (#15). */
  302.             -webkit-user-select: none; -moz-user-select: none; user-select: none;
  303.             -webkit-touch-callout: none;
  304.             width: 110px;
  305.             border: 2px solid #ddd;
  306.             border-radius: 10px;
  307.             overflow: hidden;
  308.             transition: border-color 0.2s, box-shadow 0.2s;
  309.             background: #fff;
  310.             text-decoration: none;
  311.             color: #333;
  312.             display: block;
  313.         }
  314.         /* Gate :hover behind real hover-capable pointers. On iOS Safari a
  315.            :hover rule that changes appearance makes the first tap apply the
  316.            hover state and suppresses the click, so the option chip needed a
  317.            second tap to fire its onclick (is-selected + price update). */
  318.         @media (hover: hover) and (pointer: fine) {
  319.             .rp-card:hover {
  320.                 border-color: #999;
  321.                 box-shadow: 0 2px 8px rgba(0,0,0,0.1);
  322.             }
  323.         }
  324.         .rp-card.is-selected {
  325.             border-color: #1a6fcf;
  326.             box-shadow: 0 2px 10px rgba(26,111,207,0.25);
  327.         }
  328.         /* visually-hidden instead of display:none. A label wrapping a
  329.            display:none radio fires its tap unreliably on iOS Safari (first tap
  330.            often ignored -> \"2回タッチ\"). Keeping the input in the layout but
  331.            invisible makes the first tap register. */
  332.         .rp-card input[type=\"radio\"] {
  333.             position: absolute; opacity: 0; width: 1px; height: 1px;
  334.             margin: 0; pointer-events: none;
  335.         }
  336.         .rp-card__image {
  337.             width: 100%;
  338.             aspect-ratio: 1 / 1;
  339.             object-fit: cover;
  340.             display: block;
  341.             background: #f5f5f5;
  342.         }
  343.         .rp-card__placeholder {
  344.             width: 100%;
  345.             aspect-ratio: 1 / 1;
  346.             background: #f0f0f0;
  347.             display: flex;
  348.             align-items: center;
  349.             justify-content: center;
  350.             color: #bbb;
  351.             font-size: 24px;
  352.         }
  353.         .rp-card__name {
  354.             display: block;
  355.             padding: 5px 5px;
  356.             font-size: 11px;
  357.             color: #333;
  358.             text-align: center;
  359.             line-height: 1.4;
  360.             word-break: break-all;
  361.         }
  362.         .rp-card.is-selected .rp-card__name { color: #1a6fcf; font-weight: bold; }
  363.         .rp-card.is-selected::after {
  364.             content: \"✓\";
  365.             position: absolute;
  366.             top: 3px; right: 6px;
  367.             color: #1a6fcf;
  368.             font-size: 13px;
  369.             font-weight: bold;
  370.         }
  371.         /* ---- 2. ボタン式ラジオ(画像なし・8個以内)---- */
  372.         .rp-btn-group {
  373.             display: flex;
  374.             flex-wrap: wrap;
  375.             gap: 8px;
  376.             margin-bottom: 4px;
  377.             max-width: 100%;
  378.             min-width: 0;
  379.         }
  380.         .rp-btn {
  381.             cursor: pointer;
  382.             touch-action: manipulation; /* drop iOS 300ms tap delay (#15) */
  383.             -webkit-tap-highlight-color: rgba(0,0,0,0);
  384.             /* iOS Safari: block first-tap text selection so 1 tap switches (#15) */
  385.             -webkit-user-select: none; -moz-user-select: none; user-select: none;
  386.             -webkit-touch-callout: none;
  387.             padding: 8px 14px;
  388.             border: 2px solid #ddd;
  389.             border-radius: 10px;
  390.             font-size: 13px;
  391.             color: #333;
  392.             background: #fff;
  393.             transition: border-color 0.2s, background 0.2s;
  394.             white-space: normal;
  395.             max-width: 100%;
  396.             overflow-wrap: anywhere;
  397.             text-decoration: none;
  398.         }
  399.         @media (hover: hover) and (pointer: fine) {
  400.             .rp-btn:hover { border-color: #999; }
  401.         }
  402.         .rp-btn.is-selected {
  403.             border-color: #1a6fcf;
  404.             color: #1a6fcf;
  405.             font-weight: bold;
  406.             background: #f0f6ff;
  407.         }
  408.         .rp-btn input[type=\"radio\"] {
  409.             position: absolute; opacity: 0; width: 1px; height: 1px;
  410.             margin: 0; pointer-events: none;
  411.         }
  412.         /* iOS Safari \"2回タッチ\" fix for the type-selection link chips.
  413.            The global theme stylesheet ships an ungated `a:hover{color:#296292}`
  414.            (paired with `a{color:#337ab7;text-decoration:underline}`). Because
  415.            .rp-btn / .rp-card are real <a> links, iOS Safari applies that hover
  416.            colour on the FIRST tap — the chip text turns blue (#296292, the
  417.            reported \"字だけ青くなる\") — and treats the tap as a hover, swallowing
  418.            the navigation so a 2nd tap was needed. The local .rp-*:hover rules
  419.            are already gated behind (hover:hover), but this inherited global
  420.            rule was not. Pin the hover/active colour to the base/selected colour
  421.            so tapping produces no visual change and the first tap navigates
  422.            immediately. Higher specificity (0,2,0 / 0,3,0) overrides a:hover. */
  423.         .rp-btn:hover,
  424.         .rp-btn:active { color: #333; text-decoration: none; }
  425.         .rp-btn.is-selected:hover,
  426.         .rp-btn.is-selected:active { color: #1a6fcf; text-decoration: none; }
  427.         .rp-card:hover,
  428.         .rp-card:active { color: #333; text-decoration: none; }
  429.         .rp-card:hover .rp-card__name,
  430.         .rp-card:active .rp-card__name { color: #333; }
  431.         .rp-card.is-selected:hover .rp-card__name,
  432.         .rp-card.is-selected:active .rp-card__name { color: #1a6fcf; }
  433.         /* ---- 選択肢が多い場合: 縦3段に収めて横スクロール(顧客要望「3列くらいで横スクロール」)---- */
  434.         /* grid-auto-flow:column + 3行固定 → 選択肢が縦に最大3段、超過分は右へ伸び横スクロールで閲覧 */
  435.         .rp-btn-group.is-scroll,
  436.         .opt-btn-group.is-scroll {
  437.             display: grid;
  438.             grid-auto-flow: column;
  439.             grid-template-rows: repeat(3, auto);
  440.             grid-auto-columns: max-content;
  441.             justify-content: start;
  442.             align-items: start;
  443.             gap: 8px;
  444.             overflow-x: auto;
  445.             overflow-y: hidden;
  446.             -webkit-overflow-scrolling: touch;
  447.             scrollbar-width: thin;
  448.             /* 上下に余白を確保して、行の枠線が overflow クリップ/スクロールバーに
  449.                切り取られないようにする(「文字列が長いと下枠が消える」対策)。 */
  450.             padding: 2px 0 12px;
  451.         }
  452.         /* is-scroll(横スクロール)内では選択肢を折り返さず単一行に固定する。
  453.            折り返すと行高が不揃いになり overflow-y:hidden で下枠が切れるため、
  454.            長い選択肢は折り返さず横スクロールで見せる(本来の設計意図)。 */
  455.         .rp-btn-group.is-scroll .rp-btn,
  456.         .rp-btn-group.is-scroll .opt-btn,
  457.         .opt-btn-group.is-scroll .rp-btn,
  458.         .opt-btn-group.is-scroll .opt-btn {
  459.             white-space: nowrap;
  460.             word-break: normal;
  461.             overflow-wrap: normal;
  462.         }
  463.         .rp-btn-group.is-scroll::-webkit-scrollbar,
  464.         .opt-btn-group.is-scroll::-webkit-scrollbar {
  465.             height: 6px;
  466.         }
  467.         .rp-btn-group.is-scroll::-webkit-scrollbar-thumb,
  468.         .opt-btn-group.is-scroll::-webkit-scrollbar-thumb {
  469.             background: #c0c0c0;
  470.             border-radius: 3px;
  471.         }
  472.         /* ---- 3. プルダウン(画像なし・9個以上)---- */
  473.         .rp-select-wrap {
  474.             margin-bottom: 4px;
  475.         }
  476.         .rp-select {
  477.             width: 100%;
  478.             max-width: 420px;
  479.             padding: 8px 12px;
  480.             border: 2px solid #ddd;
  481.             border-radius: 10px;
  482.             font-size: 13px;
  483.             color: #333;
  484.             background: #fff;
  485.             appearance: none;
  486.             background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%23666' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E\");
  487.             background-repeat: no-repeat;
  488.             background-position: right 12px center;
  489.             cursor: pointer;
  490.         }
  491.         .rp-select:focus {
  492.             outline: none;
  493.             border-color: #1a6fcf;
  494.         }
  495.         /* ---- オプション選択ボタン(枠線ラジオ)---- */
  496.         .opt-btn-group {
  497.             display: flex;
  498.             flex-wrap: wrap;
  499.             gap: 8px;
  500.             padding: 6px 0;
  501.             max-width: 100%;
  502.             min-width: 0;
  503.         }
  504.         .opt-btn {
  505.             cursor: pointer;
  506.             touch-action: manipulation; /* drop iOS 300ms tap delay (#15) */
  507.             -webkit-tap-highlight-color: rgba(0,0,0,0);
  508.             /* iOS Safari: block first-tap text selection so 1 tap switches (#15) */
  509.             -webkit-user-select: none; -moz-user-select: none; user-select: none;
  510.             -webkit-touch-callout: none;
  511.             padding: 7px 14px;
  512.             border: 2px solid #ddd;
  513.             border-radius: 10px;
  514.             font-size: 13px;
  515.             color: #333;
  516.             background: #fff;
  517.             transition: border-color 0.2s, background 0.2s;
  518.             white-space: normal;
  519.             max-width: 100%;
  520.             overflow-wrap: anywhere;
  521.             text-decoration: none;
  522.         }
  523.         @media (hover: hover) and (pointer: fine) {
  524.             .opt-btn:hover { border-color: #999; }
  525.         }
  526.         .opt-btn.is-selected {
  527.             border-color: #1a6fcf;
  528.             color: #1a6fcf;
  529.             font-weight: bold;
  530.             background: #f0f6ff;
  531.         }
  532.         .opt-btn input[type=\"radio\"] {
  533.             position: absolute; opacity: 0; width: 1px; height: 1px;
  534.             margin: 0; pointer-events: none;
  535.         }
  536.         /* opt-btn with color swatch image. The label still works as a
  537.            radio target — clicking the image checks the input. The text
  538.            label stays under the image so users can still read the name. */
  539.         .opt-btn--with-image {
  540.             padding: 4px 6px 6px;
  541.             white-space: normal;
  542.             text-align: center;
  543.             display: inline-flex;
  544.             flex-direction: column;
  545.             align-items: center;
  546.             min-width: 96px;
  547.             max-width: 140px;
  548.         }
  549.         .opt-btn--with-image .opt-btn__img {
  550.             display: block;
  551.             width: 88px;
  552.             height: 66px;
  553.             object-fit: cover;
  554.             border-radius: 6px;
  555.             margin-bottom: 4px;
  556.             background: #f5f5f5;
  557.         }
  558.         .opt-btn--with-image .opt-btn__name {
  559.             display: block;
  560.             font-size: 11px;
  561.             line-height: 1.3;
  562.             color: inherit;
  563.         }
  564.         .opt-btn--with-image.is-selected .opt-btn__img {
  565.             outline: 2px solid #1a6fcf;
  566.             outline-offset: 1px;
  567.         }
  568.         /* sale_type=2 (内窓) 補助金対象ガラスの強調表示.
  569.            補助金が出る性能区分 (真空断熱 / Low-E複層 等) のガラス選択肢に
  570.            緑枠 + 「補助金対象」バッジを付け、選択前から判別できるようにする。 */
  571.         .opt-btn--subsidy {
  572.             border-color: #2e7d32;
  573.         }
  574.         .opt-btn--subsidy.is-selected {
  575.             border-color: #1a6fcf;
  576.         }
  577.         .opt-btn__subsidy-badge {
  578.             display: inline-block;
  579.             margin-left: 6px;
  580.             padding: 1px 6px;
  581.             border-radius: 6px;
  582.             background: #2e7d32;
  583.             color: #fff;
  584.             font-size: 11px;
  585.             font-weight: bold;
  586.             white-space: nowrap;
  587.         }
  588.         /* ============================================
  589.            施工エリア案内
  590.         ============================================ */
  591.         .ec-areaNotice {
  592.             margin: 16px 0;
  593.             padding: 16px 20px;
  594.             background: #f8f9fa;
  595.             border-left: 4px solid #1a6fcf;
  596.             border-radius: 0 8px 8px 0;
  597.         }
  598.         .ec-areaNotice__inner {
  599.             display: flex;
  600.             align-items: flex-start;
  601.             gap: 12px;
  602.         }
  603.         .ec-areaNotice__icon {
  604.             font-size: 22px;
  605.             line-height: 1;
  606.             flex-shrink: 0;
  607.             margin-top: 2px;
  608.         }
  609.         .ec-areaNotice__body {
  610.             flex: 1;
  611.         }
  612.         .ec-areaNotice__title {
  613.             font-size: 13px;
  614.             font-weight: bold;
  615.             color: #1a6fcf;
  616.             margin: 0 0 6px;
  617.         }
  618.         .ec-areaNotice__text {
  619.             font-size: 13px;
  620.             color: #444;
  621.             line-height: 1.7;
  622.             margin: 0;
  623.         }
  624.         .ec-areaNotice__text strong {
  625.             color: #222;
  626.         }
  627.         .ec-areaNotice__link {
  628.             display: inline-block;
  629.             margin-top: 8px;
  630.             font-size: 12px;
  631.             color: #1a6fcf;
  632.             text-decoration: underline;
  633.         }
  634.         .ec-areaNotice__link:hover {
  635.             color: #0d4fa0;
  636.         }
  637.         /* ============================================
  638.            SNSシェア + ブランド名 タイトル行
  639.         ============================================ */
  640.         .ec-productRole__titleRow {
  641.             display: flex;
  642.             align-items: center;
  643.             justify-content: space-between;
  644.             gap: 8px;
  645.             margin-bottom: 4px;
  646.         }
  647.         .ec-productRole__titleRow .ec-headingTitle {
  648.             margin: 0;
  649.             flex: 1;
  650.             font-size: 18px;
  651.         }
  652.         .ec-share-inline {
  653.             display: flex;
  654.             align-items: center;
  655.             gap: 8px;
  656.             flex-shrink: 0;
  657.         }
  658.         @media (max-width: 767px) {
  659.             /* maker_area の float を解除して独立表示 */
  660.             #maker_area {
  661.                 float: none !important;
  662.                 width: auto !important;
  663.                 height: auto !important;
  664.                 display: block;
  665.                 margin-bottom: 4px;
  666.             }
  667.             /* タイトル行: 商品名が全幅を占有しSNSは右寄せ下段 */
  668.             .ec-productRole__titleRow {
  669.                 flex-wrap: wrap;
  670.                 clear: both;
  671.             }
  672.             .ec-productRole__titleRow .ec-headingTitle {
  673.                 flex: 1 1 100%;
  674.                 font-size: 16px;
  675.             }
  676.             .ec-share-inline {
  677.                 flex: 0 0 auto;
  678.                 margin-left: auto;
  679.             }
  680.         }
  681.         .ec-share-inline a {
  682.             display: flex;
  683.             align-items: center;
  684.             justify-content: center;
  685.             width: 32px;
  686.             height: 32px;
  687.             border-radius: 50%;
  688.             font-size: 15px;
  689.             color: #fff;
  690.             text-decoration: none;
  691.             transition: opacity 0.2s;
  692.         }
  693.         .ec-share-inline a:hover { opacity: 0.8; }
  694.         .ec-share-inline .share-twitter  { background: #000; }
  695.         .ec-share-inline .share-facebook { background: linear-gradient(45deg, #f09433, #e6683c, #dc2743, #cc2366, #bc1888); }
  696.         .ec-share-inline .share-line     { background: #06c755; }
  697.         /* description_detail下のシェアブロックはPC/スマホ共通で非表示(タイトル行に移動) */
  698.         .ec-productRole__share { display: none; }
  699.         /* ============================================
  700.            PC用: 現在のお見積り額カード強調
  701.         ============================================ */
  702.         @media (min-width: 768px) {
  703.             .mitsumori-card-pc {
  704.                 border: 2px solid #1a6fcf !important;
  705.                 border-radius: 10px !important;
  706.                 box-shadow: 0 4px 16px rgba(26,111,207,0.18) !important;
  707.                 margin-top: 20px;
  708.                 overflow: hidden;
  709.                 background: linear-gradient(135deg, #1a6fcf, #0d4fa0) !important;
  710.             }
  711.             .mitsumori-card-pc .card-header {
  712.                 background: linear-gradient(135deg, #1a6fcf, #0d4fa0) !important;
  713.                 color: #fff !important;
  714.                 padding: 14px 16px !important;
  715.                 border-bottom: none !important;
  716.             }
  717.             .mitsumori-card-pc .card-title {
  718.                 color: #fff !important;
  719.                 font-size: 15px !important;
  720.                 font-weight: bold !important;
  721.                 margin: 0 !important;
  722.             }
  723.             .mitsumori-card-pc #mitsumori_message {
  724.                 font-size: 22px !important;
  725.                 font-weight: bold !important;
  726.                 color: #fff !important;
  727.             }
  728.             .mitsumori-card-pc .btn-tool {
  729.                 color: #fff !important;
  730.             }
  731.             /* 合計行を大きく強調 */
  732.             .mitsumori-card-pc .nav-item:first-child .nav-link {
  733.                 font-size: 16px !important;
  734.                 font-weight: bold !important;
  735.                 color: #c00 !important;
  736.                 background: #fff8f8 !important;
  737.                 padding: 12px 16px !important;
  738.             }
  739.             .mitsumori-card-pc .nav-item:first-child #mitsumori_goukei {
  740.                 font-size: 20px !important;
  741.                 font-weight: bold !important;
  742.                 color: #c00 !important;
  743.             }
  744.             /* card-body(明細リスト)を白背景に */
  745.             .mitsumori-card-pc .card-body {
  746.                 background: #fff !important;
  747.             }
  748.             .mitsumori-card-pc .card-footer {
  749.                 background: #f8faff !important;
  750.                 border-top: 1px solid #dce8fb !important;
  751.                 padding: 12px 16px !important;
  752.             }
  753.         }
  754.         @media (max-width: 767px) {
  755.             /* スマホでは現在のお見積り額カードの強調スタイルをすべてリセット */
  756.             .mitsumori-card-pc {
  757.                 border: none !important;
  758.                 border-radius: 0 !important;
  759.                 box-shadow: none !important;
  760.                 margin-top: 0 !important;
  761.                 overflow: visible !important;
  762.                 background: none !important;
  763.                 /* sticky-top(position:sticky / z-index:1020) を解除。
  764.                    そのままだと最下部で #sp-mitsumori-bar(z-index:1000) の上に
  765.                    重なり、合計バーと文字が被るため通常フローへ戻す。 */
  766.                 position: static !important;
  767.                 z-index: auto !important;
  768.             }
  769.             .mitsumori-card-pc .card-header {
  770.                 background: none !important;
  771.                 color: inherit !important;
  772.                 padding: inherit !important;
  773.                 border-bottom: inherit !important;
  774.             }
  775.             .mitsumori-card-pc .card-title { color: inherit !important; }
  776.             .mitsumori-card-pc #mitsumori_message { font-size: inherit !important; color: inherit !important; }
  777.             .mitsumori-card-pc .btn-tool { color: inherit !important; }
  778.             /* 折りたたみトグルボタン */
  779.             .btn-mitsumori-toggle {
  780.                 background: none !important;
  781.                 border: 1px solid #aaa !important;
  782.                 border-radius: 4px !important;
  783.                 padding: 2px 8px !important;
  784.                 font-size: 12px !important;
  785.                 color: #333 !important;
  786.                 line-height: 1.4 !important;
  787.             }
  788.             .btn-mitsumori-toggle .toggle-icon {
  789.                 display: inline-block;
  790.                 transition: transform 0.2s;
  791.             }
  792.             /* 展開状態: ▼→▲ */
  793.             .card:not(.collapsed-card) .btn-mitsumori-toggle .toggle-icon::before {
  794.                 content: \"▲ 閉じる\";
  795.             }
  796.             .card:not(.collapsed-card) .btn-mitsumori-toggle .toggle-icon {
  797.                 display: none;
  798.             }
  799.             .card:not(.collapsed-card) .btn-mitsumori-toggle::after {
  800.                 content: \"▲ 閉じる\";
  801.                 font-size: 12px;
  802.             }
  803.             .mitsumori-card-pc .nav-item:first-child .nav-link {
  804.                 font-size: inherit !important;
  805.                 color: inherit !important;
  806.                 background: none !important;
  807.                 padding: inherit !important;
  808.             }
  809.             .mitsumori-card-pc .nav-item:first-child #mitsumori_goukei {
  810.                 font-size: inherit !important;
  811.                 color: inherit !important;
  812.             }
  813.             .mitsumori-card-pc .card-footer {
  814.                 background: none !important;
  815.                 border-top: inherit !important;
  816.                 padding: inherit !important;
  817.             }
  818.             /* 横スクロール禁止 */
  819.             body, html {
  820.                 overflow-x: hidden;
  821.                 max-width: 100vw;
  822.             }
  823.             /* ボタンの折り返しを許可(nowrapが原因で横スクロール発生するため) */
  824.             .opt-btn,
  825.             .rp-btn {
  826.                 white-space: normal;
  827.                 word-break: break-all;
  828.             }
  829.             /* エリア案内: スマホでコンパクト */
  830.             .ec-areaNotice {
  831.                 margin: 8px 0;
  832.                 padding: 8px 10px;
  833.                 border-left-width: 3px;
  834.                 cursor: pointer;
  835.             }
  836.             .ec-areaNotice__inner {
  837.                 flex-direction: row;
  838.                 gap: 8px;
  839.                 align-items: flex-start;
  840.             }
  841.             .ec-areaNotice__icon { font-size: 15px; }
  842.             /* タイトル行: 展開トグル */
  843.             .ec-areaNotice__title {
  844.                 font-size: 11px;
  845.                 margin-bottom: 3px;
  846.                 display: flex;
  847.                 justify-content: space-between;
  848.                 align-items: center;
  849.             }
  850.             .ec-areaNotice__title::after {
  851.                 content: \"▼\";
  852.                 font-size: 9px;
  853.                 color: #888;
  854.                 margin-left: 6px;
  855.                 transition: transform 0.2s;
  856.             }
  857.             .ec-areaNotice.is-open .ec-areaNotice__title::after {
  858.                 transform: rotate(180deg);
  859.             }
  860.             /* 折りたたみ対象: 閉じた状態では非表示 */
  861.             .ec-areaNotice__detail {
  862.                 display: none;
  863.             }
  864.             .ec-areaNotice.is-open .ec-areaNotice__detail {
  865.                 display: block;
  866.             }
  867.             .ec-areaNotice__text { font-size: 11px; line-height: 1.5; }
  868.             .ec-areaNotice__text br { display: none; }
  869.             .ec-areaNotice__link { font-size: 11px; margin-top: 3px; }
  870.             .rp-card { width: calc(33.333% - 6px); min-width: 80px; }
  871.             
  872.             #sp-mitsumori-bar {
  873.                 display: flex;
  874.                 position: fixed;
  875.                 bottom: 0;
  876.                 left: 0;
  877.                 right: 0;
  878.                 z-index: 1000;
  879.                 background: #fff;
  880.                 border-top: 2px solid #e0e0e0;
  881.                 box-shadow: 0 -2px 8px rgba(0,0,0,0.12);
  882.                 align-items: center;
  883.                 padding: 8px 10px calc(8px + env(safe-area-inset-bottom)) 10px;
  884.                 gap: 8px;
  885.             }
  886.             #sp-mitsumori-bar .sp-bar__label {
  887.                 font-size: 11px;
  888.                 color: #666;
  889.                 white-space: nowrap;
  890.             }
  891.             /* 価格ラッパ: 合計金額は最重要のため常に全桁表示する(縮小・省略しない)。
  892.                幅が足りない場合は下のボタン側を縮める(flex 配分でボタンが先に縮む)。 */
  893.             #sp-mitsumori-bar .sp-bar__pricewrap {
  894.                 flex: 0 0 auto;
  895.                 min-width: 0;
  896.             }
  897.             #sp-mitsumori-bar .sp-bar__price {
  898.                 font-size: 18px;
  899.                 font-weight: bold;
  900.                 color: #c00;
  901.                 white-space: nowrap;
  902.             }
  903.             #sp-mitsumori-bar .sp-bar__btn {
  904.                 font-size: 12px;
  905.                 padding: 8px 12px;
  906.                 background: #333;
  907.                 color: #fff;
  908.                 border: none;
  909.                 border-radius: 6px;
  910.                 white-space: nowrap;
  911.                 cursor: pointer;
  912.                 position: relative;
  913.                 display: inline-flex;
  914.                 align-items: center;
  915.                 gap: 6px;
  916.                 flex: 1 1 auto;
  917.                 min-width: 0;
  918.                 justify-content: center;
  919.             }
  920.             #sp-mitsumori-bar .sp-bar__btn i {
  921.                 font-size: 14px;
  922.                 flex: 0 0 auto;
  923.             }
  924.             /* お見積りの詳細(内訳)を開くボタン。価格・カートボタンを圧迫しないよう
  925.                最小幅のアイコン+短ラベルにし、幅不足時も縮まない固定幅で維持する。 */
  926.             #sp-mitsumori-bar .sp-bar__detail-btn {
  927.                 display: inline-flex;
  928.                 flex-direction: column;
  929.                 align-items: center;
  930.                 justify-content: center;
  931.                 gap: 2px;
  932.                 flex: 0 0 auto;
  933.                 padding: 4px 8px;
  934.                 background: #fff;
  935.                 color: #c00;
  936.                 border: 1px solid #c00;
  937.                 border-radius: 6px;
  938.                 font-size: 10px;
  939.                 font-weight: bold;
  940.                 line-height: 1.1;
  941.                 white-space: nowrap;
  942.                 cursor: pointer;
  943.             }
  944.             #sp-mitsumori-bar .sp-bar__detail-btn i { font-size: 15px; }
  945.             /* 幅が足りないときはボタンの文字を省略し、価格と数字を守る。 */
  946.             #sp-mitsumori-bar .sp-bar__btn-label {
  947.                 overflow: hidden;
  948.                 text-overflow: ellipsis;
  949.                 white-space: nowrap;
  950.             }
  951.             #sp-mitsumori-bar .sp-bar__cart-badge {
  952.                 position: absolute;
  953.                 top: -6px;
  954.                 right: -6px;
  955.                 background: #c00;
  956.                 color: #fff;
  957.                 border-radius: 50%;
  958.                 min-width: 16px;
  959.                 height: 16px;
  960.                 font-size: 10px;
  961.                 line-height: 16px;
  962.                 padding: 0 4px;
  963.                 font-weight: bold;
  964.             }
  965.             #sp-mitsumori-bar .sp-bar__home-btn {
  966.                 display: inline-flex;
  967.                 align-items: center;
  968.                 justify-content: center;
  969.                 width: 36px;
  970.                 height: 36px;
  971.                 flex: 0 0 auto;
  972.                 border: 1px solid #ccc;
  973.                 border-radius: 6px;
  974.                 background: #fff;
  975.                 color: #333;
  976.                 text-decoration: none;
  977.                 cursor: pointer;
  978.             }
  979.             #sp-mitsumori-bar .sp-bar__home-btn i {
  980.                 font-size: 16px;
  981.             }
  982.             #sp-mitsumori-bar .sp-bar__home-btn:hover {
  983.                 background: #f0f0f0;
  984.             }
  985.             /* 下部バーの高さ分ページ下部にpaddingを追加 (iOS safe-area 込み) */
  986.             body {
  987.                 padding-bottom: calc(80px + env(safe-area-inset-bottom));
  988.             }
  989.         }
  990.         /* ============================================
  991.            カート追加モーダル: 縦並び中央配置
  992.         ============================================ */
  993.         .add-cart-modal__wrap {
  994.             text-align: center;
  995.         }
  996.         .add-cart-modal__header {
  997.             font-size: 16px;
  998.             margin: 20px 0 24px;
  999.             text-align: center;
  1000.         }
  1001.         .add-cart-modal__actions {
  1002.             display: flex;
  1003.             flex-direction: column;
  1004.             align-items: center;
  1005.             gap: 16px;
  1006.             padding: 0 20px 20px;
  1007.         }
  1008.         .add-cart-modal__primary {
  1009.             display: inline-block;
  1010.             width: 80%;
  1011.             max-width: 320px;
  1012.             padding: 14px 20px;
  1013.             font-size: 15px;
  1014.             font-weight: bold;
  1015.             text-align: center;
  1016.             background: #d9534f;
  1017.             color: #fff !important;
  1018.             border-radius: 6px;
  1019.             text-decoration: none;
  1020.             cursor: pointer;
  1021.         }
  1022.         .add-cart-modal__primary:hover {
  1023.             background: #c9302c;
  1024.             color: #fff !important;
  1025.             text-decoration: none;
  1026.         }
  1027.         .add-cart-modal__secondary {
  1028.             display: inline-block;
  1029.             padding: 6px 14px;
  1030.             font-size: 12px;
  1031.             color: #666;
  1032.             border: 1px solid #ccc;
  1033.             border-radius: 4px;
  1034.             background: #fff;
  1035.             cursor: pointer;
  1036.         }
  1037.         .add-cart-modal__secondary:hover {
  1038.             background: #f0f0f0;
  1039.             color: #333;
  1040.         }
  1041.         @media (max-width: 767px) {
  1042.             .add-cart-modal__actions {
  1043.                 gap: 20px;
  1044.             }
  1045.         }
  1046.     </style>
  1047. ";
  1048.         
  1049.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->leave($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof);
  1050.         
  1051.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->leave($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof);
  1052.     }
  1053.     // line 1037
  1054.     public function block_javascript($context, array $blocks = [])
  1055.     {
  1056.         $macros $this->macros;
  1057.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  1058.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->enter($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""javascript"));
  1059.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02 $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  1060.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->enter($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""javascript"));
  1061.         // line 1038
  1062.         echo "
  1063.     <script>
  1064.         eccube.classCategories = ";
  1065.         // line 1040
  1066.         echo $this->extensions['Eccube\Twig\Extension\EccubeExtension']->getClassCategoriesAsJson((isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'1040$this->source); })()));
  1067.         echo ";
  1068.         // 規格2に選択肢を割り当てる。
  1069.         function fnSetClassCategories(form, classcat_id2_selected) {
  1070.             var \$form = \$(form);
  1071.             var product_id = \$form.find('input[name=product_id]').val();
  1072.             var \$sele1 = \$form.find('select[name=classcategory_id1]');
  1073.             var \$sele2 = \$form.find('select[name=classcategory_id2]');
  1074.             eccube.setClassCategories(\$form, product_id, \$sele1, \$sele2, classcat_id2_selected);
  1075.         }
  1076.         ";
  1077.         // line 1051
  1078.         if (twig_get_attribute($this->env$this->source, ($context["form"] ?? null), "classcategory_id2", [], "any"truetruefalse1051)) {
  1079.             // line 1052
  1080.             echo "        fnSetClassCategories(
  1081.             \$('#form1'), ";
  1082.             // line 1053
  1083.             echo json_encode(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["form"]) || array_key_exists("form"$context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.'1053$this->source); })()), "classcategory_id2", [], "any"falsefalsefalse1053), "vars", [], "any"falsefalsefalse1053), "value", [], "any"falsefalsefalse1053));
  1084.             echo "
  1085.         );
  1086.         ";
  1087.         } elseif (twig_get_attribute($this->env$this->source,         // line 1055
  1088. ($context["form"] ?? null), "classcategory_id1", [], "any"truetruefalse1055)) {
  1089.             // line 1056
  1090.             echo "        eccube.checkStock(\$('#form1'), ";
  1091.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'1056$this->source); })()), "id", [], "any"falsefalsefalse1056), "html"nulltrue);
  1092.             echo ", ";
  1093.             echo json_encode(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["form"]) || array_key_exists("form"$context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.'1056$this->source); })()), "classcategory_id1", [], "any"falsefalsefalse1056), "vars", [], "any"falsefalsefalse1056), "value", [], "any"falsefalsefalse1056));
  1094.             echo ", null);
  1095.         ";
  1096.         }
  1097.         // line 1058
  1098.         echo "    </script>
  1099.     <script>
  1100.         \$(function() {
  1101.             // bfcache無効化
  1102.             \$(window).bind('pageshow', function(event) {
  1103.                 if (event.originalEvent.persisted) {
  1104.                     location.reload(true);
  1105.                 }
  1106.             });
  1107.             // Core Web Vital の Cumulative Layout Shift(CLS)対策のため
  1108.             // img タグに width, height が付与されている.
  1109.             // 630px 未満の画面サイズでは縦横比が壊れるための対策
  1110.             // see https://github.com/EC-CUBE/ec-cube/pull/5023
  1111.             \$('.ec-grid2__cell').hide();
  1112.             var removeSize = function () {
  1113.                 \$('.slide-item').height('');
  1114.                 \$('.slide-item img')
  1115.                     .removeAttr('width')
  1116.                     .removeAttr('height')
  1117.                     .removeAttr('style');
  1118.             };
  1119.             var slickInitial = function(slick) {
  1120.                 \$('.ec-grid2__cell').fadeIn(1500);
  1121.                 var baseHeight = \$(slick.target).height();
  1122.                 var baseWidth = \$(slick.target).width();
  1123.                 var rate = baseWidth / baseHeight;
  1124. \t\t\t\tif(baseHeight * rate < 400){
  1125. \t                \$('.slide-item').height(baseHeight * rate); // 余白を削除する
  1126. \t\t\t\t}else{
  1127. \t                \$('.slide-item').height(400); // 余白を削除する
  1128. \t\t\t\t}
  1129.                 // transform を使用することでCLSの影響を受けないようにする
  1130.                 \$('.slide-item img')
  1131.                     .css(
  1132.                         {
  1133.                             'transform-origin': 'top left',
  1134.                             'transform': 'scaleY(' + rate + ')',
  1135.                             'transition': 'transform .1s'
  1136.                         }
  1137.                     );
  1138.                 // 正しいサイズに近くなったら属性を解除する
  1139.                 setTimeout(removeSize, 500);
  1140.             };
  1141.             \$('.item_visual').on('init', slickInitial);
  1142.             // リサイズ時は CLS の影響を受けないため属性を解除する
  1143.             \$(window).resize(removeSize);
  1144.             \$('.item_visual').slick({
  1145.                 dots: false,
  1146.                 arrows: true,
  1147.                 responsive: [{
  1148.                     breakpoint: 768,
  1149.                     settings: {
  1150.                         dots: true,
  1151.                 \t\tarrows: false
  1152.                     }
  1153.                 }]
  1154.             });
  1155.             \$('.slideThumb').on('click', function() {
  1156.                 var index = \$(this).attr('data-index');
  1157.                 \$('.item_visual').slick('slickGoTo', index, false);
  1158.             })
  1159.         });
  1160.     </script>
  1161.     <script>
  1162.         \$(function() {
  1163.             \$('.add-cart').on('click', function(event) {
  1164.                 ";
  1165.         // line 1128
  1166.         if (twig_get_attribute($this->env$this->source, ($context["form"] ?? null), "classcategory_id1", [], "any"truetruefalse1128)) {
  1167.             // line 1129
  1168.             echo "                // 規格1フォームの必須チェック
  1169.                 if (\$('#classcategory_id1').val() == '__unselected' || \$('#classcategory_id1').val() == '') {
  1170.                     \$('#classcategory_id1')[0].setCustomValidity('";
  1171.             // line 1131
  1172.             echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\TranslationExtension']->trans("項目が選択されていません"), "html"nulltrue);
  1173.             echo "');
  1174.                     return true;
  1175.                 } else {
  1176.                     \$('#classcategory_id1')[0].setCustomValidity('');
  1177.                 }
  1178.                 ";
  1179.         }
  1180.         // line 1137
  1181.         echo "
  1182.                 ";
  1183.         // line 1138
  1184.         if (twig_get_attribute($this->env$this->source, ($context["form"] ?? null), "classcategory_id2", [], "any"truetruefalse1138)) {
  1185.             // line 1139
  1186.             echo "                // 規格2フォームの必須チェック
  1187.                 if (\$('#classcategory_id2').val() == '__unselected' || \$('#classcategory_id2').val() == '') {
  1188.                     \$('#classcategory_id2')[0].setCustomValidity('";
  1189.             // line 1141
  1190.             echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\TranslationExtension']->trans("項目が選択されていません"), "html"nulltrue);
  1191.             echo "');
  1192.                     return true;
  1193.                 } else {
  1194.                     \$('#classcategory_id2')[0].setCustomValidity('');
  1195.                 }
  1196.                 ";
  1197.         }
  1198.         // line 1147
  1199.         echo "
  1200.                 // タイプ2: カート送信直前に set_count を quantity に同期
  1201.                 if(\$('#set_count').length){
  1202.                     var _sc = parseInt(\$('#set_count').val()) || 1;
  1203.                     \$('#quantity').val(_sc);
  1204.                     \$('input[name=\"quantity\"]').val(_sc);
  1205.                 }
  1206.                 // 個数フォームのチェック
  1207.                 if (\$('#quantity').val() < 1) {
  1208.                     \$('#quantity')[0].setCustomValidity('";
  1209.         // line 1157
  1210.         echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\TranslationExtension']->trans("1以上で入力してください。"), "html"nulltrue);
  1211.         echo "');
  1212.                     return true;
  1213.                 } else {
  1214.                     \$('#quantity')[0].setCustomValidity('');
  1215.                 }
  1216.                 event.preventDefault();
  1217.                 \$form = \$('#form1');
  1218.                 \$.ajax({
  1219.                     url: \$form.attr('action'),
  1220.                     type: \$form.attr('method'),
  1221.                     data: \$form.serialize(),
  1222.                     dataType: 'json',
  1223.                     beforeSend: function(xhr, settings) {
  1224.                         // Buttonを無効にする
  1225.                         \$('.add-cart').prop('disabled', true);
  1226.                     }
  1227.                 }).done(function(data) {
  1228.                     // レスポンス内のメッセージをalertで表示
  1229.                     \$.each(data.messages, function() {
  1230.                         \$('#ec-modal-header').text(this);
  1231.                     });
  1232.                     \$('.ec-modal').show()
  1233.                     // カートブロックを更新する
  1234.                     \$.ajax({
  1235.                         url: \"";
  1236.         // line 1184
  1237.         echo $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getUrl("block_cart");
  1238.         echo "\",
  1239.                         type: 'GET',
  1240.                         dataType: 'html'
  1241.                     }).done(function(html) {
  1242.                         \$('.ec-headerRole__cart').html(html);
  1243.                     });
  1244.                 }).fail(function(data) {
  1245.                     alert('";
  1246.         // line 1191
  1247.         echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\TranslationExtension']->trans("カートへの追加に失敗しました。"), "html"nulltrue);
  1248.         echo "');
  1249.                 }).always(function(data) {
  1250.                     // Buttonを有効にする
  1251.                     \$('.add-cart').prop('disabled', false);
  1252.                 });
  1253.             });
  1254.         });
  1255.         \$('.ec-modal-wrap').on('click', function(e) {
  1256.             // モーダル内の処理は外側にバブリングさせない
  1257.             e.stopPropagation();
  1258.         });
  1259.         \$('.ec-modal-overlay, .ec-modal, .ec-modal-close, .ec-inlineBtn--cancel').on('click', function() {
  1260.             \$('.ec-modal').hide()
  1261.         });
  1262. \t\tvar pw = \"";
  1263.         // line 1208
  1264.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1208$this->source); })())) {
  1265.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1208$this->source); })()), "pw", [], "any"falsefalsefalse1208), "html"nulltrue);
  1266.         }
  1267.         echo "\";
  1268. \t\tvar pd = \"";
  1269.         // line 1209
  1270.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1209$this->source); })())) {
  1271.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1209$this->source); })()), "pd", [], "any"falsefalsefalse1209), "html"nulltrue);
  1272.         }
  1273.         echo "\";
  1274. \t\tvar ph = \"";
  1275.         // line 1210
  1276.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1210$this->source); })())) {
  1277.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1210$this->source); })()), "ph", [], "any"falsefalsefalse1210), "html"nulltrue);
  1278.         }
  1279.         echo "\";
  1280. \t\tvar pm = \"";
  1281.         // line 1211
  1282.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1211$this->source); })())) {
  1283.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1211$this->source); })()), "pm", [], "any"falsefalsefalse1211), "html"nulltrue);
  1284.         }
  1285.         echo "\";
  1286. \t\tvar pc = \"";
  1287.         // line 1212
  1288.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1212$this->source); })())) {
  1289.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1212$this->source); })()), "pc", [], "any"falsefalsefalse1212), "html"nulltrue);
  1290.         }
  1291.         echo "\";
  1292. \t\t// option1 / option2: カテゴリ別 option 軸 (um: タイプ=subtype, fe: ct_up 等)
  1293. \t\tvar option1 = \"";
  1294.         // line 1214
  1295.         if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1214$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "option1", [], "any"truetruefalse1214))) {
  1296.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1214$this->source); })()), "option1", [], "any"falsefalsefalse1214), "html"nulltrue);
  1297.         }
  1298.         echo "\";
  1299. \t\tvar option2 = \"";
  1300.         // line 1215
  1301.         if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1215$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "option2", [], "any"truetruefalse1215))) {
  1302.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1215$this->source); })()), "option2", [], "any"falsefalsefalse1215), "html"nulltrue);
  1303.         }
  1304.         echo "\";
  1305. \t\tvar op0 = \"";
  1306.         // line 1216
  1307.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1216$this->source); })())) {
  1308.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1216$this->source); })()), "op", [], "any"falsefalsefalse1216), 0, [], "array"falsefalsefalse1216), "html"nulltrue);
  1309.         }
  1310.         echo "\";
  1311. \t\tvar op1 = \"";
  1312.         // line 1217
  1313.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1217$this->source); })())) {
  1314.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1217$this->source); })()), "op", [], "any"falsefalsefalse1217), 1, [], "array"falsefalsefalse1217), "html"nulltrue);
  1315.         }
  1316.         echo "\";
  1317. \t\tvar op2 = \"";
  1318.         // line 1218
  1319.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1218$this->source); })())) {
  1320.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1218$this->source); })()), "op", [], "any"falsefalsefalse1218), 2, [], "array"falsefalsefalse1218), "html"nulltrue);
  1321.         }
  1322.         echo "\";
  1323. \t\tvar op3 = \"";
  1324.         // line 1219
  1325.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1219$this->source); })())) {
  1326.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1219$this->source); })()), "op", [], "any"falsefalsefalse1219), 3, [], "array"falsefalsefalse1219), "html"nulltrue);
  1327.         }
  1328.         echo "\";
  1329. \t\tvar op4 = \"";
  1330.         // line 1220
  1331.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1220$this->source); })())) {
  1332.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1220$this->source); })()), "op", [], "any"falsefalsefalse1220), 4, [], "array"falsefalsefalse1220), "html"nulltrue);
  1333.         }
  1334.         echo "\";
  1335. \t\tvar op5 = \"";
  1336.         // line 1221
  1337.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1221$this->source); })())) {
  1338.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1221$this->source); })()), "op", [], "any"falsefalsefalse1221), 5, [], "array"falsefalsefalse1221), "html"nulltrue);
  1339.         }
  1340.         echo "\";
  1341. \t\tvar op6 = \"";
  1342.         // line 1222
  1343.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1222$this->source); })())) {
  1344.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1222$this->source); })()), "op", [], "any"falsefalsefalse1222), 6, [], "array"falsefalsefalse1222), "html"nulltrue);
  1345.         }
  1346.         echo "\";
  1347. \t\tvar op7 = \"";
  1348.         // line 1223
  1349.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1223$this->source); })())) {
  1350.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1223$this->source); })()), "op", [], "any"falsefalsefalse1223), 7, [], "array"falsefalsefalse1223), "html"nulltrue);
  1351.         }
  1352.         echo "\";
  1353. \t\tvar op8 = \"";
  1354.         // line 1224
  1355.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1224$this->source); })())) {
  1356.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1224$this->source); })()), "op", [], "any"falsefalsefalse1224), 8, [], "array"falsefalsefalse1224), "html"nulltrue);
  1357.         }
  1358.         echo "\";
  1359. \t\tvar op9 = \"";
  1360.         // line 1225
  1361.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1225$this->source); })())) {
  1362.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1225$this->source); })()), "op", [], "any"falsefalsefalse1225), 9, [], "array"falsefalsefalse1225), "html"nulltrue);
  1363.         }
  1364.         echo "\";
  1365. \t\tvar op10 = \"";
  1366.         // line 1226
  1367.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1226$this->source); })())) {
  1368.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1226$this->source); })()), "op", [], "any"falsefalsefalse1226), 10, [], "array"falsefalsefalse1226), "html"nulltrue);
  1369.         }
  1370.         echo "\";
  1371. \t\tconst formatter = new Intl.NumberFormat('ja-JP');
  1372. \t\t// ============================================================
  1373. \t\t//  free_area 1 エントリのスキーマ(11 キー固定)
  1374. \t\t// ============================================================
  1375. \t\t//   w           : 幅 (string, 例 \"239.9cm\" / tf は \"1m\")
  1376. \t\t//   d           : 奥行
  1377. \t\t//   h           : 高さ (tf はロール長 \"10m\")
  1378. \t\t//   m           : 素材
  1379. \t\t//   c           : カラー
  1380. \t\t//   price       : 販売価格 (税抜、amount=1 ベース)
  1381. \t\t//   unit_price  : 商品 per-unit 増分 (税抜、AMOUNT_CATEGORIES のみ)
  1382. \t\t//   maker_price : メーカー価格 (税抜)
  1383. \t\t//   ct          : 基本工事費 (税抜、amount=1 ベース)
  1384. \t\t//   option1     : fe → ct_up / その他カテゴリ → category-specific
  1385. \t\t//   option2     : um → ct_up / その他カテゴリ → category-specific
  1386. \t\t//
  1387. \t\t//  ct4 (設置場所) / ct5 (撤去) / ct6 (残土) は option_area 側で扱う.
  1388. \t\t// ============================================================
  1389. \t\t// 施工オプション定義(option_area)— 各エントリ {name, comment, on, off, price}
  1390. \t\tvar op_data = ";
  1391.         // line 1249
  1392.         echo ((array_key_exists("op_json"$context)) ? (_twig_default_filter((isset($context["op_json"]) || array_key_exists("op_json"$context) ? $context["op_json"] : (function () { throw new RuntimeError('Variable "op_json" does not exist.'1249$this->source); })()), "[]")) : ("[]"));
  1393.         echo ";
  1394. \t\t// option_item_area:
  1395. \t\t//   tg 用 — block 別オプション差額表
  1396. \t\t//     { axis_labels: {F:'床材',front:'前面型',side1:'右側面型',side2:'左側面型'},
  1397. \t\t//       blocks: { 'W_label|D_label': { F:[{idx,label,diff},...], front:[...], side1:[...], side2:[...] }, ... } }
  1398. \t\t//   fe (sale_type=4) 用 — ブロックの種類×段数の差額表 (fe_block キー)
  1399. \t\t//     { fe_block: { depends_on_name: '...', depends_on_value: '...',
  1400. \t\t//                   title: '...', default_key: '...',
  1401. \t\t//                   choices: [{key,label,price}, ...] } }
  1402. \t\t// 該当しないカテゴリでは fe_block は null. axis_labels/blocks は空.
  1403. \t\tvar oi_data = ";
  1404.         // line 1260
  1405.         echo ((array_key_exists("oi_json"$context)) ? (_twig_default_filter((isset($context["oi_json"]) || array_key_exists("oi_json"$context) ? $context["oi_json"] : (function () { throw new RuntimeError('Variable "oi_json" does not exist.'1260$this->source); })()), "{\"axis_labels\":{},\"blocks\":{},\"fe_block\":null}")) : ("{\"axis_labels\":{},\"blocks\":{},\"fe_block\":null}"));
  1406.         echo ";
  1407. \t\t// 選択中の tg オプション差額 (axis -> selected choice_idx). ラジオ click で更新される.
  1408. \t\tvar oi_selected = { F: 1, front: 1, side1: 1, side2: 1 };
  1409. \t\t// 選択中の fe ブロック種類×段数 (key 文字列). 既定は oi_data.fe_block.default_key.
  1410. \t\tvar fe_block_selected = (oi_data && oi_data.fe_block && oi_data.fe_block.default_key) || '';
  1411. \t\t// sale_type ID(mtb_sale_type の id。本サイトでの意味は次の通り):
  1412. \t\t//   1 通常 / 2 補助金窓 / 3 物置 / 4 フェンス / 5 デッキ / 6 芝生 / 9 商品のみ
  1413. \t\tvar SALE_TYPE_ID = ";
  1414.         // line 1270
  1415.         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'1270$this->source); })()), "SaleType", [], "any"falsefalsefalse1270), "id", [], "any"falsefalsefalse1270), "html"nulltrue);
  1416.         echo ";
  1417. \t\t";
  1418.         // line 1273
  1419.         echo "\t\t";
  1420.         $context["option1_label"] = "オプション1";
  1421.         // line 1274
  1422.         echo "\t\t";
  1423.         $context["option2_label"] = "オプション2";
  1424.         // line 1275
  1425.         echo "\t\t";
  1426.         if ( !twig_test_empty(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'1275$this->source); })()), "ProductCategories", [], "any"falsefalsefalse1275))) {
  1427.             // line 1276
  1428.             echo "\t\t\t";
  1429.             $context['_parent'] = $context;
  1430.             $context['_seq'] = twig_ensure_traversable(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'1276$this->source); })()), "ProductCategories", [], "any"falsefalsefalse1276));
  1431.             foreach ($context['_seq'] as $context["_key"] => $context["pcat"]) {
  1432.                 // line 1277
  1433.                 echo "\t\t\t\t";
  1434.                 if ((twig_get_attribute($this->env$this->source$context["pcat"], "category_id", [], "any"falsefalsefalse1277) == 31)) {
  1435.                     $context["option1_label"] = "サイズプリセット";
  1436.                     $context["option2_label"] = "駆動方式";
  1437.                 }
  1438.                 // line 1278
  1439.                 echo "\t\t\t\t";
  1440.                 if ((twig_get_attribute($this->env$this->source$context["pcat"], "category_id", [], "any"falsefalsefalse1278) == 43)) {
  1441.                     $context["option1_label"] = "ランマ";
  1442.                     $context["option2_label"] = "タイプ";
  1443.                 }
  1444.                 // line 1279
  1445.                 echo "\t\t\t\t";
  1446.                 if ((twig_get_attribute($this->env$this->source$context["pcat"], "category_id", [], "any"falsefalsefalse1279) == 15)) {
  1447.                     $context["option1_label"] = "棚タイプ";
  1448.                 }
  1449.                 // line 1280
  1450.                 echo "\t\t\t\t";
  1451.                 if ((twig_get_attribute($this->env$this->source$context["pcat"], "category_id", [], "any"falsefalsefalse1280) == 17)) {
  1452.                     $context["option1_label"] = "窓タイプ";
  1453.                 }
  1454.                 // line 1281
  1455.                 echo "\t\t\t";
  1456.             }
  1457.             $_parent $context['_parent'];
  1458.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pcat'], $context['_parent'], $context['loop']);
  1459.             $context array_intersect_key($context$_parent) + $_parent;
  1460.             // line 1282
  1461.             echo "\t\t";
  1462.         }
  1463.         // line 1283
  1464.         echo "
  1465. \t\t// 消費税率(pp.price/pp.ct/op_data.price は scraper が税抜で保存しているため、
  1466. \t\t// calcGoukei 出口で 1+TAX_RATE を掛けて税込 mitsumori_goukei にする)
  1467. \t\tvar TAX_RATE = 0.10;
  1468. \t\tfunction toIncTax(v) { return Math.round(v * (1 + TAX_RATE)); }
  1469. \t\t/**
  1470. \t\t * tg 用 block 別オプション差額の集計.
  1471. \t\t *   現選択 (W, D) から block key を作り、oi_data.blocks[blockKey] を取得.
  1472. \t\t *   各 axis (F/front/side1/side2) で oi_selected[axis] の choice の diff を合計.
  1473. \t\t * 戻り値: { total: 差額合計(税抜), items: [{name, label, diff}, ...] }
  1474. \t\t *   block が無い (tg 以外 / 該当 (W,D) が未取得) なら total=0.
  1475. \t\t */
  1476. \t\tfunction collectOptionItems(curW, curD) {
  1477. \t\t\tvar result = { total: 0, items: [] };
  1478. \t\t\tif (!oi_data || !oi_data.blocks) return result;
  1479. \t\t\tvar blockKey = (curW || '') + '|' + (curD || '');
  1480. \t\t\tvar block = oi_data.blocks[blockKey];
  1481. \t\t\tif (!block) return result;
  1482. \t\t\tvar axes = ['F', 'front', 'side1', 'side2'];
  1483. \t\t\tfor (var i = 0; i < axes.length; i++) {
  1484. \t\t\t\tvar axis = axes[i];
  1485. \t\t\t\tvar choices = block[axis];
  1486. \t\t\t\tif (!choices || !choices.length) continue;
  1487. \t\t\t\tvar idx = oi_selected[axis] || 1;
  1488. \t\t\t\tvar pick = null;
  1489. \t\t\t\tfor (var j = 0; j < choices.length; j++) {
  1490. \t\t\t\t\tif (parseInt(choices[j].idx) === parseInt(idx)) { pick = choices[j]; break; }
  1491. \t\t\t\t}
  1492. \t\t\t\tif (!pick) pick = choices[0];
  1493. \t\t\t\tvar diff = parseInt(pick.diff) || 0;
  1494. \t\t\t\tresult.total += diff;
  1495. \t\t\t\tresult.items.push({
  1496. \t\t\t\t\tname:  oi_data.axis_labels[axis] || axis,
  1497. \t\t\t\t\tlabel: pick.label,
  1498. \t\t\t\t\tdiff:  diff,
  1499. \t\t\t\t});
  1500. \t\t\t}
  1501. \t\t\treturn result;
  1502. \t\t}
  1503. \t\t/**
  1504. \t\t * tg ラジオ群を block 別に DOM へ描画する.
  1505. \t\t *   W/D が確定したら現 block の 4 軸 (F/front/side1/side2) ラジオを #tg-options 要素に出す.
  1506. \t\t *   block が空なら #tg-options を空にする.
  1507. \t\t */
  1508. \t\tfunction renderOptionItemRadios(curW, curD) {
  1509. \t\t\tvar \$box = \$('#tg-options');
  1510. \t\t\tif (!\$box.length) return;
  1511. \t\t\t\$box.empty();
  1512. \t\t\tif (!oi_data || !oi_data.blocks) return;
  1513. \t\t\tvar blockKey = (curW || '') + '|' + (curD || '');
  1514. \t\t\tvar block = oi_data.blocks[blockKey];
  1515. \t\t\tif (!block) return;
  1516. \t\t\tvar axes = ['F', 'front', 'side1', 'side2'];
  1517. \t\t\taxes.forEach(function(axis) {
  1518. \t\t\t\tvar choices = block[axis];
  1519. \t\t\t\tif (!choices || !choices.length) return;
  1520. \t\t\t\tvar axisLabel = (oi_data.axis_labels && oi_data.axis_labels[axis]) || axis;
  1521. \t\t\t\tvar \$section = \$('<div class=\"form-group tg-axis\"></div>');
  1522. \t\t\t\t\$section.append('<p class=\"rp-section-label\"><strong>' + axisLabel + '</strong>: <span class=\"tg-axis-selected\"></span></p>');
  1523. \t\t\t\tvar \$list = \$('<div class=\"tg-choice-list\"></div>');
  1524. \t\t\t\tchoices.forEach(function(ch, i) {
  1525. \t\t\t\t\tvar inputId = 'tg_' + axis + '_' + ch.idx;
  1526. \t\t\t\t\tvar name = 'tg_' + axis;
  1527. \t\t\t\t\tvar checked = (parseInt(ch.idx) === parseInt(oi_selected[axis] || 1)) ? ' checked' : '';
  1528. \t\t\t\t\tvar diffTxt = ch.diff > 0 ? '+' + formatter.format(ch.diff) + '円' : (ch.diff < 0 ? formatter.format(ch.diff) + '円' : '±0');
  1529. \t\t\t\t\t\$list.append(
  1530. \t\t\t\t\t\t'<label class=\"tg-choice\"><input type=\"radio\" name=\"' + name + '\" id=\"' + inputId + '\" value=\"' + ch.idx + '\" data-axis=\"' + axis + '\"' + checked + '> ' +
  1531. \t\t\t\t\t\tch.label + '<span class=\"tg-diff\">(' + diffTxt + ')</span></label>'
  1532. \t\t\t\t\t);
  1533. \t\t\t\t});
  1534. \t\t\t\t\$section.append(\$list);
  1535. \t\t\t\t\$box.append(\$section);
  1536. \t\t\t});
  1537. \t\t\t// ラジオ click で oi_selected を更新 → 再計算
  1538. \t\t\t\$box.off('change.tg').on('change.tg', 'input[type=\"radio\"][data-axis]', function() {
  1539. \t\t\t\tvar axis = \$(this).data('axis');
  1540. \t\t\t\toi_selected[axis] = parseInt(\$(this).val()) || 1;
  1541. \t\t\t\tmitsumori_simulation('refresh', '');
  1542. \t\t\t});
  1543. \t\t\tupdateOptionItemSelectedLabels();
  1544. \t\t}
  1545. \t\tfunction updateOptionItemSelectedLabels() {
  1546. \t\t\t\$('#tg-options .tg-axis').each(function() {
  1547. \t\t\t\tvar \$sel = \$(this).find('input[type=\"radio\"]:checked');
  1548. \t\t\t\tif (!\$sel.length) return;
  1549. \t\t\t\tvar label = \$sel.parent().contents().filter(function() { return this.nodeType === 3; }).text().trim();
  1550. \t\t\t\t\$(this).find('.tg-axis-selected').text(label);
  1551. \t\t\t});
  1552. \t\t}
  1553. \t\t// =========================================================
  1554. \t\t// fe (sale_type=4) ブロック種類×段数 サブ UI
  1555. \t\t// =========================================================
  1556. \t\t/**
  1557. \t\t * fe_block の親オプション (= op_data 内の「ご希望のフェンス設置方法」 entry)
  1558. \t\t * を name でルックアップし、その index を返す. 見つからなければ -1.
  1559. \t\t *   fe_block.depends_on_name が設定されていればそれで照合.
  1560. \t\t *   未設定なら 'ご希望のフェンス設置方法' を含む name にフォールバック.
  1561. \t\t */
  1562. \t\tfunction findFeBlockParentOpIndex() {
  1563. \t\t\tif (!oi_data || !oi_data.fe_block) return -1;
  1564. \t\t\tvar needle = oi_data.fe_block.depends_on_name || 'ご希望のフェンス設置方法';
  1565. \t\t\tfor (var i = 0; i < op_data.length; i++) {
  1566. \t\t\t\tif (!op_data[i] || !op_data[i].name) continue;
  1567. \t\t\t\tif (op_data[i].name.indexOf(needle) >= 0) return i;
  1568. \t\t\t}
  1569. \t\t\treturn -1;
  1570. \t\t}
  1571. \t\t/**
  1572. \t\t * fe_block の現在の選択値の price (税抜) と choice 内容を集計.
  1573. \t\t *   親オプション (= 'ご希望のフェンス設置方法') が depends_on_value を選んでいる
  1574. \t\t *   ときだけ加算する. それ以外 (既存ブロック側 / 親未選択) は price=0.
  1575. \t\t * 戻り値: { price: 0|N, choice: {key,label,price}|null, active: bool }
  1576. \t\t */
  1577. \t\tfunction collectFeBlock() {
  1578. \t\t\tvar result = { price: 0, choice: null, active: false };
  1579. \t\t\tif (SALE_TYPE_ID !== 4) return result;
  1580. \t\t\tif (!oi_data || !oi_data.fe_block) return result;
  1581. \t\t\tif (!oi_data.fe_block.choices || !oi_data.fe_block.choices.length) return result;
  1582. \t\t\tvar parentIdx = findFeBlockParentOpIndex();
  1583. \t\t\tif (parentIdx < 0) return result;
  1584. \t\t\tvar ops = [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10];
  1585. \t\t\tvar parentSel = ops[parentIdx];
  1586. \t\t\tvar triggerValue = oi_data.fe_block.depends_on_value || '新規にブロック積みを行う';
  1587. \t\t\tif (parentSel !== triggerValue) return result;  // 親が新規ブロック積み以外なら無加算
  1588. \t\t\tresult.active = true;
  1589. \t\t\tvar choices = oi_data.fe_block.choices;
  1590. \t\t\tvar pick = null;
  1591. \t\t\tfor (var j = 0; j < choices.length; j++) {
  1592. \t\t\t\tif (choices[j].key === fe_block_selected) { pick = choices[j]; break; }
  1593. \t\t\t}
  1594. \t\t\tif (!pick) pick = choices[0];
  1595. \t\t\tresult.choice = pick;
  1596. \t\t\tresult.price  = parseInt(pick.price) || 0;
  1597. \t\t\treturn result;
  1598. \t\t}
  1599. \t\t/**
  1600. \t\t * fe_block ラジオ群を #fe-block-options 要素に描画する.
  1601. \t\t *   active=false (親が「新規にブロック積み」以外) のときは非表示.
  1602. \t\t */
  1603. \t\tfunction renderFeBlockRadios() {
  1604. \t\t\tvar \$box = \$('#fe-block-options');
  1605. \t\t\tif (!\$box.length) return;
  1606. \t\t\tif (!oi_data || !oi_data.fe_block || !oi_data.fe_block.choices) {
  1607. \t\t\t\t\$box.empty().hide();
  1608. \t\t\t\treturn;
  1609. \t\t\t}
  1610. \t\t\tvar parentIdx = findFeBlockParentOpIndex();
  1611. \t\t\tif (parentIdx < 0) {
  1612. \t\t\t\t\$box.empty().hide();
  1613. \t\t\t\treturn;
  1614. \t\t\t}
  1615. \t\t\tvar ops = [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10];
  1616. \t\t\tvar triggerValue = oi_data.fe_block.depends_on_value || '新規にブロック積みを行う';
  1617. \t\t\tvar visible = (ops[parentIdx] === triggerValue);
  1618. \t\t\tif (!visible) {
  1619. \t\t\t\t\$box.hide();
  1620. \t\t\t\treturn;
  1621. \t\t\t}
  1622. \t\t\tvar fb = oi_data.fe_block;
  1623. \t\t\t\$box.empty();
  1624. \t\t\tvar \$title = \$('<p class=\"rp-section-label\"><strong>' + (fb.title || 'ブロックの種類と段数') + '</strong></p>');
  1625. \t\t\t\$box.append(\$title);
  1626. \t\t\t// 他オプション群と同じ .opt-btn-group / .opt-btn 形式で描画.
  1627. \t\t\t//   生の <label><input type=radio> ... 形式だと CSS 定義が無く
  1628. \t\t\t//   ラベル折り返し・縦ズレ・隣接 opt-btn との間隔不揃いが発生する.
  1629. \t\t\tvar \$list = \$('<div class=\"opt-btn-group\" style=\"flex-direction:column;align-items:stretch;\"></div>');
  1630. \t\t\tfb.choices.forEach(function(ch) {
  1631. \t\t\t\tvar inputId = 'fe_block_' + ch.key;
  1632. \t\t\t\tvar isSel   = (ch.key === fe_block_selected);
  1633. \t\t\t\tvar checked = isSel ? ' checked' : '';
  1634. \t\t\t\tvar selCls  = isSel ? ' is-selected' : '';
  1635. \t\t\t\tvar priceTxt = (parseInt(ch.price) || 0) > 0
  1636. \t\t\t\t\t? ' <span class=\"fe-block-price\" style=\"margin-left:6px;color:#666;font-size:12px;white-space:nowrap;\">(+' + formatter.format(toIncTax(parseInt(ch.price))) + '円 税込)</span>'
  1637. \t\t\t\t\t: '';
  1638. \t\t\t\t\$list.append(
  1639. \t\t\t\t\t'<label class=\"opt-btn' + selCls + '\" style=\"text-align:left;display:flex;align-items:center;flex-wrap:wrap;\">' +
  1640. \t\t\t\t\t'<input type=\"radio\" name=\"fe_block\" id=\"' + inputId + '\" value=\"' + ch.key + '\"' + checked + '>' +
  1641. \t\t\t\t\t'<span class=\"fe-block-label\">' + ch.label + '</span>' +
  1642. \t\t\t\t\tpriceTxt +
  1643. \t\t\t\t\t'</label>'
  1644. \t\t\t\t);
  1645. \t\t\t});
  1646. \t\t\t\$box.append(\$list);
  1647. \t\t\t\$box.show();
  1648. \t\t\t\$box.off('change.fe_block').on('change.fe_block', 'input[type=\"radio\"][name=\"fe_block\"]', function() {
  1649. \t\t\t\tfe_block_selected = \$(this).val();
  1650. \t\t\t\t// is-selected 切替 (opt-btn 形式共通)
  1651. \t\t\t\t\$box.find('label.opt-btn').removeClass('is-selected');
  1652. \t\t\t\t\$(this).closest('label.opt-btn').addClass('is-selected');
  1653. \t\t\t\tmitsumori_simulation('refresh', '');
  1654. \t\t\t});
  1655. \t\t}
  1656. \t\t/**
  1657. \t\t * fe (sale_type=4) で op_data エントリの連動表示制御.
  1658. \t\t *   親「ご希望のフェンス設置方法」の選択値に応じて、
  1659. \t\t *     - 「既存ブロックに穴空け工事が必要ですか?」 entry を表示/非表示
  1660. \t\t *   切替の trigger は親選択値の文字列で判定 (entry index にハードコードしない).
  1661. \t\t */
  1662. \t\tfunction updateFeOpConditionalVisibility() {
  1663. \t\t\tif (SALE_TYPE_ID !== 4) return;
  1664. \t\t\tvar parentIdx = findFeBlockParentOpIndex();
  1665. \t\t\tif (parentIdx < 0) return;
  1666. \t\t\tvar ops = [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10];
  1667. \t\t\tvar parentSel = ops[parentIdx];
  1668. \t\t\t// 親が「既存ブロックに設置する」 (= off 側) のとき穴空け entry を表示
  1669. \t\t\tvar triggerOffValue = (op_data[parentIdx] && op_data[parentIdx].off) || '既存ブロックに設置する';
  1670. \t\t\t\$('div[data-op-name]').each(function() {
  1671. \t\t\t\tvar n = \$(this).attr('data-op-name') || '';
  1672. \t\t\t\tif (n.indexOf('穴空け') >= 0) {
  1673. \t\t\t\t\tif (parentSel === triggerOffValue) {
  1674. \t\t\t\t\t\t\$(this).show();
  1675. \t\t\t\t\t} else {
  1676. \t\t\t\t\t\t\$(this).hide();
  1677. \t\t\t\t\t}
  1678. \t\t\t\t}
  1679. \t\t\t});
  1680. \t\t}
  1681. \t\t/**
  1682. \t\t * 選択中の施工オプションを集計し、ON選択分の price を合計する.
  1683. \t\t * 戻り値: { total: 合計金額, items: [{name, value, price}, ...] }
  1684. \t\t */
  1685. \t\tfunction collectOptions() {
  1686. \t\t\tvar ops = [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10];
  1687. \t\t\tvar total = 0;
  1688. \t\t\tvar items = [];
  1689. \t\t\tfor (var i = 0; i < ops.length; i++) {
  1690. \t\t\t\tif (!op_data[i] || !op_data[i].name) continue;
  1691. \t\t\t\tvar sel = ops[i];
  1692. \t\t\t\tif (!sel) continue;
  1693. \t\t\t\tvar price = parseInt(op_data[i].price) || 0;
  1694. \t\t\t\t// 「ON」選択時のみ加算(OFF や「不要」「商品購入のみ」は加算しない)
  1695. \t\t\t\tvar isOn = (sel === op_data[i].on);
  1696. \t\t\t\titems.push({
  1697. \t\t\t\t\tname:  op_data[i].name,
  1698. \t\t\t\t\tvalue: sel,
  1699. \t\t\t\t\tprice: isOn ? price : 0,
  1700. \t\t\t\t\ton:    op_data[i].on,
  1701. \t\t\t\t\toff:   op_data[i].off,
  1702. \t\t\t\t});
  1703. \t\t\t\tif (isOn) total += price;
  1704. \t\t\t}
  1705. \t\t\t// fe (sale_type=4) のブロック種類×段数 分を items / total に統合.
  1706. \t\t\t// 親オプション「ご希望のフェンス設置方法」 が 「新規にブロック積みを行う」 のとき
  1707. \t\t\t// だけ加算される (collectFeBlock 内で判定済み).
  1708. \t\t\tvar fb = collectFeBlock();
  1709. \t\t\tif (fb.active && fb.choice) {
  1710. \t\t\t\titems.push({
  1711. \t\t\t\t\tname:  (oi_data.fe_block && oi_data.fe_block.title) || 'ブロックの種類と段数',
  1712. \t\t\t\t\tvalue: fb.choice.label,
  1713. \t\t\t\t\tprice: fb.price,
  1714. \t\t\t\t\ton:    fb.choice.label,
  1715. \t\t\t\t\toff:   '',
  1716. \t\t\t\t});
  1717. \t\t\t\ttotal += fb.price;
  1718. \t\t\t}
  1719. \t\t\treturn { total: total, items: items };
  1720. \t\t}
  1721. \t\t/**
  1722. \t\t * free_area 1 エントリ ({w,d,h,m,c,price,unit_price,maker_price,ct,option1,option2})
  1723. \t\t * から sale_type 別に最終金額を算出する.
  1724. \t\t *
  1725. \t\t * 計算式(amount=1 ベース、出口で × 1.10 税込化):
  1726. \t\t *   1 通常        : price + ct + option_sum
  1727. \t\t *   2 補助金窓    : price × set_count + (ct + (set_count-1) × option2) + option_sum
  1728. \t\t *   3 物置        : (price + ct) × daisu + option_sum
  1729. \t\t *   4 フェンス    : price + (maisu-1) × unit_price
  1730. \t\t *                  + ct + max(0, maisu-3) × option1
  1731. \t\t *                  + option_sum   (maisu >= 3)
  1732. \t\t *   5 デッキ      : price + ct + option_sum   (area は表示用、計算非関与)
  1733. \t\t *   6 芝生        : price × ceil(area / (w_m × h_m)) + ct + option_sum
  1734. \t\t *   9 商品のみ    : price のみ(カート quantity 倍で総額)
  1735. \t\t *
  1736. \t\t * fe では option1 を ct_up、um では option2 を ct_up として転用.
  1737. \t\t * tf では w / h にロール幅・長さが格納されており parseLen で数値抽出.
  1738. \t\t *
  1739. \t\t * @param {Object} pp  free_area の 1 行(matrix エントリ)
  1740. \t\t * @param {number} optionTotal  collectOptions().total
  1741. \t\t * @param {Object} ctx  UI 入力 {set_count, daisu, maisu, area, quantityOnly, ...}
  1742. \t\t * @returns {Object} {goukei, price, ct, opt, qty}  すべて税込整数
  1743. \t\t */
  1744. \t\tfunction calcGoukei(pp, optionTotal, ctx) {
  1745. \t\t\tvar basePrice  = parseInt(pp.price)       || 0;
  1746. \t\t\tvar baseCt     = parseInt(pp.ct)          || 0;
  1747. \t\t\tvar unitPrice  = parseInt(pp.unit_price)  || 0;
  1748. \t\t\tvar optSum     = optionTotal;
  1749. \t\t\tvar price      = basePrice;
  1750. \t\t\tvar ct         = baseCt;
  1751. \t\t\tvar qty        = 1;
  1752. \t\t\tvar goukei     = 0;
  1753. \t\t\t// 「商品購入のみ」選択時は工事費・オプションをゼロにする(任意 sale_type で適用)
  1754. \t\t\tvar ops = [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10];
  1755. \t\t\tvar purchaseOnly = ops.some(function(v){ return v === '商品購入のみ'; });
  1756. \t\t\tif (purchaseOnly) {
  1757. \t\t\t\tbaseCt = 0;
  1758. \t\t\t\tct     = 0;
  1759. \t\t\t\toptSum = 0;
  1760. \t\t\t}
  1761. \t\t\tswitch (SALE_TYPE_ID) {
  1762. \t\t\t\tcase 2: {  // 補助金・窓 (シンプル表引き方式 2026-05-)
  1763. \t\t\t\t\t// 2026-05 仕様簡素化: 枚数軸を廃止し、subtype に枚数を内包.
  1764. \t\t\t\t\t// pp.price / pp.ct は (W, H, ガラス, subtype) の単一価格.
  1765. \t\t\t\t\t// 複数枚をまとめて買う場合はカート quantity で表現.
  1766. \t\t\t\t\tqty    = 1;
  1767. \t\t\t\t\tprice  = basePrice;
  1768. \t\t\t\t\tct     = baseCt;
  1769. \t\t\t\t\tgoukei = price + ct + optSum;
  1770. \t\t\t\t\tbreak;
  1771. \t\t\t\t}
  1772. \t\t\t\tcase 3: {  // 物置・ゴミステーション
  1773. \t\t\t\t\tqty   = Math.max(1, parseInt(ctx.daisu) || 1);
  1774. \t\t\t\t\tprice = basePrice * qty;
  1775. \t\t\t\t\tct    = baseCt * qty;
  1776. \t\t\t\t\tgoukei = price + ct + optSum;
  1777. \t\t\t\t\tbreak;
  1778. \t\t\t\t}
  1779. \t\t\t\tcase 4: {  // フェンス・組み立て式(maisu ≥ 3、base_amount = 3)
  1780. \t\t\t\t\t// scraper は amount=3 を base にしているので pp.price = price(3),
  1781. \t\t\t\t\t// pp.unit_price = price(4) - price(3).
  1782. \t\t\t\t\tqty   = Math.max(3, parseInt(ctx.maisu) || 3);
  1783. \t\t\t\t\tprice = basePrice + (qty - 3) * unitPrice;
  1784. \t\t\t\t\t// option1 が ct_up (4枚目以降の増分). 未設定なら ct 固定動作
  1785. \t\t\t\t\tvar ctUp1 = parseInt(pp.option1) || 0;
  1786. \t\t\t\t\tct = baseCt + Math.max(0, qty - 3) * ctUp1;
  1787. \t\t\t\t\t// fe_block(ブロック積み段数): collectOptions が base(3枚分)を optSum に
  1788. \t\t\t\t\t// 算入済み. ブロック費も本体同様に枚数連動するため、4枚目以降は 1枚毎に
  1789. \t\t\t\t\t// choice.unit_price(= block(4)-block(3)) を加算する.
  1790. \t\t\t\t\t// (顧客指摘「何枚施工でも増える金額が同じ」の是正。unit_price 未設定の
  1791. \t\t\t\t\t//  旧データでは +0 で従来動作。)
  1792. \t\t\t\t\tif (!purchaseOnly) {
  1793. \t\t\t\t\t\tvar fbC = collectFeBlock();
  1794. \t\t\t\t\t\tif (fbC.active && fbC.choice) {
  1795. \t\t\t\t\t\t\toptSum += Math.max(0, qty - 3) * (parseInt(fbC.choice.unit_price) || 0);
  1796. \t\t\t\t\t\t}
  1797. \t\t\t\t\t}
  1798. \t\t\t\t\tgoukei = price + ct + optSum;
  1799. \t\t\t\t\tbreak;
  1800. \t\t\t\t}
  1801. \t\t\t\tcase 5: {  // ウッドデッキ・タイルデッキ
  1802. \t\t\t\t\t// area は担当者向けの参考値として保持(計算には使わない)
  1803. \t\t\t\t\tqty    = 1;
  1804. \t\t\t\t\tgoukei = basePrice + baseCt + optSum;
  1805. \t\t\t\t\tprice  = basePrice;
  1806. \t\t\t\t\tct     = baseCt;
  1807. \t\t\t\t\tbreak;
  1808. \t\t\t\t}
  1809. \t\t\t\tcase 6: {  // 芝生・人工芝(ロール単位)
  1810. \t\t\t\t\t// pp.w \"1m\", pp.h \"10m\" から数値抽出
  1811. \t\t\t\t\tvar w_m = parseLen(pp.w);
  1812. \t\t\t\t\tvar h_m = parseLen(pp.h);
  1813. \t\t\t\t\tvar rollSize = w_m * h_m;
  1814. \t\t\t\t\tif (!rollSize || rollSize <= 0) rollSize = 1;
  1815. \t\t\t\t\t// 施工サイズ(面積)があれば必要枚数を自動算出。無ければ直接指定の枚数を使う。
  1816. \t\t\t\t\tvar area  = parseFloat(ctx.area) || 0;
  1817. \t\t\t\t\tif (area > 0) {
  1818. \t\t\t\t\t\tqty = Math.max(1, Math.ceil(area / rollSize));
  1819. \t\t\t\t\t} else {
  1820. \t\t\t\t\t\tqty = Math.max(1, parseInt(ctx.tf_qty) || 1);
  1821. \t\t\t\t\t}
  1822. \t\t\t\t\tprice  = basePrice * qty;
  1823. \t\t\t\t\tct     = baseCt;
  1824. \t\t\t\t\tgoukei = price + ct + optSum;
  1825. \t\t\t\t\tbreak;
  1826. \t\t\t\t}
  1827. \t\t\t\tcase 7: {  // 数量買い・基本工事費固定(gf ガーデンファニチャー / st 石材)
  1828. \t\t\t\t\tqty    = Math.max(1, parseInt(ctx.suuryou) || 1);
  1829. \t\t\t\t\tprice  = basePrice * qty;
  1830. \t\t\t\t\tct     = baseCt;                 // ct は固定(数量に依らない)
  1831. \t\t\t\t\tgoukei = price + ct + optSum;
  1832. \t\t\t\t\tbreak;
  1833. \t\t\t\t}
  1834. \t\t\t\tcase 9: {  // 商品のみ購入
  1835. \t\t\t\t\t// カート側で quantity × unit price するため goukei は単品価格
  1836. \t\t\t\t\tqty    = parseInt(ctx.quantityOnly) || 1;
  1837. \t\t\t\t\tprice  = basePrice;
  1838. \t\t\t\t\tct     = 0;
  1839. \t\t\t\t\toptSum = 0;
  1840. \t\t\t\t\tgoukei = price;
  1841. \t\t\t\t\tbreak;
  1842. \t\t\t\t}
  1843. \t\t\t\tdefault: {  // 1: 通常(カーポート等、matrix 選択のみ)
  1844. \t\t\t\t\tqty    = 1;
  1845. \t\t\t\t\tgoukei = basePrice + baseCt + optSum;
  1846. \t\t\t\t\tbreak;
  1847. \t\t\t\t}
  1848. \t\t\t}
  1849. \t\t\t// 出口で税込化(pp.price/pp.ct/op_data.price はすべて税抜で保存されている前提)
  1850. \t\t\treturn {
  1851. \t\t\t\tgoukei: toIncTax(goukei),
  1852. \t\t\t\tprice:  toIncTax(price),
  1853. \t\t\t\tct:     toIncTax(ct),
  1854. \t\t\t\topt:    toIncTax(optSum),
  1855. \t\t\t\tqty:    qty,
  1856. \t\t\t};
  1857. \t\t}
  1858. \t\t/**
  1859. \t\t * 寸法文字列から「メートル単位の数値」を抽出する.
  1860. \t\t *
  1861. \t\t * 単位は m / cm / mm を認識し、いずれも m 単位に正規化して返す.
  1862. \t\t * 単位が無い場合は m 単位とみなす(旧 tf データ \"1m\" \"10m\" との互換).
  1863. \t\t * 数値が見つからない場合は 0 を返す(呼び出し側で fallback).
  1864. \t\t *
  1865. \t\t * 例:
  1866. \t\t *   \"1m\"     → 1
  1867. \t\t *   \"100cm\"  → 1   (2026-06 以降の m → cm 正規化に対応)
  1868. \t\t *   \"200cm\"  → 2
  1869. \t\t *   \"5.5m\"   → 5.5
  1870. \t\t *   \"1000mm\" → 1
  1871. \t\t *   \"\"       → 0
  1872. \t\t */
  1873. \t\tfunction parseLen(s) {
  1874. \t\t\tif (!s) return 0;
  1875. \t\t\tvar str = String(s);
  1876. \t\t\tvar m = str.match(/(\\d+(?:\\.\\d+)?)\\s*(mm|cm|m)?/i);
  1877. \t\t\tif (!m) return 0;
  1878. \t\t\tvar n = parseFloat(m[1]);
  1879. \t\t\tif (isNaN(n)) return 0;
  1880. \t\t\tvar unit = (m[2] || 'm').toLowerCase();
  1881. \t\t\tif (unit === 'cm') return n / 100;
  1882. \t\t\tif (unit === 'mm') return n / 1000;
  1883. \t\t\treturn n;  // 'm' or no unit
  1884. \t\t}
  1885. \t\t// pp は autoSelectFirstColor 等からも参照するので global にする
  1886. \t\tvar pp = ";
  1887.         // line 1730
  1888.         echo (isset($context["pp"]) || array_key_exists("pp"$context) ? $context["pp"] : (function () { throw new RuntimeError('Variable "pp" does not exist.'1730$this->source); })());
  1889.         echo ";
  1890. \t\t// sale_type=2 の幅 / 高さ ladder (Twig p_w / p_h を JS で参照するため).
  1891. \t\t// 入力 mm 値を pp の幅・高さバケット文字列にマッピングする際の元データ.
  1892. \t\t// p_w / p_h は連想配列で来ることがあるため Object.values で配列化する.
  1893. \t\tvar PP_W_LADDER = Object.values(";
  1894.         // line 1735
  1895.         echo json_encode(((array_key_exists("p_w"$context)) ? (_twig_default_filter((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'1735$this->source); })()), [])) : ([])));
  1896.         echo " || {});
  1897. \t\tvar PP_H_LADDER = Object.values(";
  1898.         // line 1736
  1899.         echo json_encode(((array_key_exists("p_h"$context)) ? (_twig_default_filter((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'1736$this->source); })()), [])) : ([])));
  1900.         echo " || {});
  1901. \t\t/* ============================================================
  1902. \t\t   sale_type=2 (補助金窓) 専用: 複数タイプ集計 & 補助金計算
  1903. \t\t   ============================================================
  1904. \t\t   - 入力 UI: #window-types-container 配下の .window-type-block
  1905. \t\t   - 補助金根拠: 先進的窓リノベ2026事業
  1906. \t\t     https://window-renovation2026.env.go.jp/construction/inner-window.html
  1907. \t\t   - 価格軸: (subtype, w, h, glass, color) で pp を lookup
  1908. \t\t   - 1 商品 = 1 明細 にまとめ、内訳 JSON を別途保存予定 (cart 連携は後続タスク)
  1909. \t\t   ============================================================ */
  1910. \t\t// 補助金マトリクス: [住宅区分][性能][サイズ区分] → 1 箇所あたり金額 (税抜・端数なし)
  1911. \t\tvar WINDOW_SUBSIDY_MATRIX = {
  1912. \t\t\tdetached:  { // 戸建住宅・延床240㎡以下の非住宅
  1913. \t\t\t\tP: { G: 140000, L: 89000, M: 58000, S: 36000 },
  1914. \t\t\t\tS: { G: 76000,  L: 52000, M: 34000, S: 22000 }
  1915. \t\t\t},
  1916. \t\t\tapartment: { // 低層・中高層集合住宅・240㎡超の非住宅
  1917. \t\t\t\tP: { G: 152000, L: 98000, M: 64000, S: 40000 },
  1918. \t\t\t\tS: { G: 83000,  L: 57000, M: 37000, S: 24000 }
  1919. \t\t\t}
  1920. \t\t};
  1921. \t\t// 住宅区分: 画面 UI (input[name=\"window_housing_type\"]) から取得する.
  1922. \t\t// 既定値は PFC meta_key=\"住宅区分\" を fallback (未設定なら '戸建').
  1923. \t\tvar HOUSING_TYPE_DEFAULT = ";
  1924.         // line 1762
  1925.         echo json_encode(_twig_default_filter($this->extensions['Plugin\ProductField\Twig\Extension\EccubeExtension']->getProduct_field(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'1762$this->source); })()), "id", [], "any"falsefalsefalse1762), "住宅区分"), "戸建"));
  1926.         echo ";
  1927. \t\tfunction getCurrentHousingKey() {
  1928. \t\t\tvar el = document.querySelector('input[name=\"window_housing_type\"]:checked');
  1929. \t\t\tvar v  = el ? el.value : HOUSING_TYPE_DEFAULT;
  1930. \t\t\treturn (v === '集合住宅') ? 'apartment' : 'detached';
  1931. \t\t}
  1932. \t\t// 商品シリーズ自動判定 (Product.name から)
  1933. \t\t// 根拠カタログ: YKK AP「ウチリモ」XAAAA-H26-067-1 (2026.04), 同「LiteU」XAAAA-H16-088-2,
  1934. \t\t//              三協アルミ「プラメイクEII」0142_STJ1931L, LIXIL「インプラス」(既知)
  1935. \t\tvar PRODUCT_NAME_RAW = ";
  1936.         // line 1772
  1937.         echo json_encode(((twig_get_attribute($this->env$this->source, ($context["Product"] ?? null), "name", [], "any"truetruefalse1772)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["Product"] ?? null), "name", [], "any"falsefalsefalse1772), "")) : ("")));
  1938.         echo ";
  1939. \t\tfunction detectProductSeries(name) {
  1940. \t\t\tif (!name) return null;
  1941. \t\t\tif (/ウチリモ/.test(name)) return 'uchirimo';
  1942. \t\t\tif (/プラマード\\s*U/i.test(name)) return 'pramado_u';
  1943. \t\t\tif (/インプラス/.test(name)) return 'inplus';
  1944. \t\t\tif (/プラメイク\\s*EII|プラメイクEII/i.test(name)) return 'plamake_eii';
  1945. \t\t\tif (/LiteU/i.test(name)) return 'lite_u';
  1946. \t\t\treturn null;
  1947. \t\t}
  1948. \t\t// シリーズ上限グレード:
  1949. \t\t//   'P'  = SS/P まで到達可能 (真空断熱ガラス採用シリーズ)
  1950. \t\t//   'S'  = Low-E 複層止まり (真空断熱ガラスのラインなし)
  1951. \t\t//   null = 単板のみ → 補助金対象外
  1952. \t\tvar SERIES_GRADE_CAP = {
  1953. \t\t\tuchirimo:    'P',
  1954. \t\t\tpramado_u:   'P',
  1955. \t\t\tinplus:      'S',
  1956. \t\t\tplamake_eii: 'S',
  1957. \t\t\tlite_u:      null
  1958. \t\t};
  1959. \t\tvar DETECTED_SERIES = detectProductSeries(PRODUCT_NAME_RAW);
  1960. \t\tvar SERIES_GRADE_CAP_VAL = (DETECTED_SERIES !== null && Object.prototype.hasOwnProperty.call(SERIES_GRADE_CAP, DETECTED_SERIES))
  1961. \t\t\t? SERIES_GRADE_CAP[DETECTED_SERIES]
  1962. \t\t\t: undefined;
  1963. \t\t// 商品単位グレード上限 (PFC `meta_key=補助金グレード上限` で個別上書き)
  1964. \t\t// 値: 'P' / 'SS' / 'S' / '対象外' / '無' / 'NONE' / 空文字 (未指定)
  1965. \t\tvar PRODUCT_GRADE_CAP_RAW = ";
  1966.         // line 1800
  1967.         echo json_encode(_twig_default_filter($this->extensions['Plugin\ProductField\Twig\Extension\EccubeExtension']->getProduct_field(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'1800$this->source); })()), "id", [], "any"falsefalsefalse1800), "補助金グレード上限"), ""));
  1968.         echo ";
  1969. \t\tfunction normalizeGradeCap(v) {
  1970. \t\t\tif (v === null || v === undefined || v === '') return undefined;
  1971. \t\t\tvar s = String(v).trim().toUpperCase();
  1972. \t\t\tif (s === 'NONE' || s === '対象外' || s === '無') return null;
  1973. \t\t\tif (s === 'P' || s === 'SS') return 'P';
  1974. \t\t\tif (s === 'S') return 'S';
  1975. \t\t\treturn undefined;
  1976. \t\t}
  1977. \t\tvar PRODUCT_GRADE_CAP = normalizeGradeCap(PRODUCT_GRADE_CAP_RAW);
  1978. \t\t// 窓種 (subtype = option1) ごとのグレード上限.
  1979. \t\t// 根拠: YKK AP「ウチリモ」業務用 (XAAAA-H26-067-1) の窓種別ラインナップで
  1980. \t\t//      真空ガラス (Glavenir) の設定有無を確認:
  1981. \t\t//        引違い窓 (2/3/4枚建) / 浴室仕様 引違い窓 / FIX窓        → P 到達可能
  1982. \t\t//        内開き窓 (居室/浴室) / 開き窓テラス / テラスドア類       → 真空ガラスなし → S 止まり
  1983. \t\tfunction detectSubtypeGradeCap(subtype) {
  1984. \t\t\tif (!subtype) return undefined;
  1985. \t\t\tvar s = String(subtype);
  1986. \t\t\tif (/内開|開き窓テラス|テラスドア|開き戸/.test(s)) return 'S';
  1987. \t\t\treturn undefined;
  1988. \t\t}
  1989. \t\t// クリップ: 強さは 'P' > 'S' > null (対象外). cap=null は強制対象外, cap=undefined は無効化なし.
  1990. \t\tfunction clipGradeBy(grade, cap) {
  1991. \t\t\tif (cap === undefined) return grade;
  1992. \t\t\tif (cap === null)      return null;
  1993. \t\t\tif (grade === null)    return null;
  1994. \t\t\tif (cap === 'S' && grade === 'P') return 'S';
  1995. \t\t\treturn grade;
  1996. \t\t}
  1997. \t\tfunction finalizeGlassGrade(raw, subtype) {
  1998. \t\t\tvar g = clipGradeBy(raw, SERIES_GRADE_CAP_VAL);
  1999. \t\t\tg     = clipGradeBy(g,   detectSubtypeGradeCap(subtype));
  2000. \t\t\tg     = clipGradeBy(g,   PRODUCT_GRADE_CAP);
  2001. \t\t\treturn g;
  2002. \t\t}
  2003. \t\t/**
  2004. \t\t * ガラスタイプ名から性能区分 'P' (SS, Uw≤1.1) / 'S' (Uw≤1.5) / null を判別.
  2005. \t\t * null = 補助対象外.
  2006. \t\t *
  2007. \t\t * 根拠: YKK AP「ウチリモ 内窓」業務用カタログ (XAAAA-H26-069-1) で
  2008. \t\t *       P (SS) は真空断熱ガラスのみ、Low-E はアルゴン入りでも S 止まり、
  2009. \t\t *       Low-E ガス無 + 型ガラス / フロストは 2026年4月で対象外、
  2010. \t\t *       が確認できた。アルゴン入り Low-E を P 判定する旧ルールは誤りだった。
  2011. \t\t *
  2012. \t\t * シリーズによっては P がそもそも存在しない (LIXIL インプラスは S 一律)
  2013. \t\t * ため、最終的には PFC で商品単位の上限を上書きできる仕組みが必要。
  2014. \t\t */
  2015. \t\tfunction detectGlassPerformance(glassName) {
  2016. \t\t\tif (!glassName) return null;
  2017. \t\t\tvar n = String(glassName);
  2018. \t\t\t// 補助対象外: 単板 / 和紙調 / 防音 / 防犯 / 型ガラス・フロスト (Low-E ガス無の型は 2026/4 で対象外)
  2019. \t\t\tif (/単ガラス|単板|和紙調|防音|防犯|複層\\/型|型ガラス|フロスト/.test(n)) return null;
  2020. \t\t\t// P (SS): 真空断熱ガラスのみ
  2021. \t\t\tif (/真空断熱/.test(n)) return 'P';
  2022. \t\t\t// S: Low-E 系のみ (アルゴン入りでも S 止まり)
  2023. \t\t\tif (/Low-?E/i.test(n)) return 'S';
  2024. \t\t\t// 一般複層 / ブラインドイン複層 / 複層強化 など Low-E 無しの複層は補助対象外
  2025. \t\t\treturn null;
  2026. \t\t}
  2027. \t\t/**
  2028. \t\t * 幅 mm × 高さ mm からサイズ区分 'G' (≥4.0㎡) / 'L' (2.8-3.9) / 'M' (1.6-2.7) / 'S' (0.2-1.5) / null.
  2029. \t\t * null = 補助対象外 (0.2㎡ 未満).
  2030. \t\t */
  2031. \t\tfunction detectSizeClass(w_mm, h_mm) {
  2032. \t\t\tvar w = parseFloat(w_mm) || 0;
  2033. \t\t\tvar h = parseFloat(h_mm) || 0;
  2034. \t\t\tif (w <= 0 || h <= 0) return null;
  2035. \t\t\tvar area = (w * h) / 1000000.0;
  2036. \t\t\tif (area < 0.2) return null;
  2037. \t\t\tif (area < 1.6) return 'S';
  2038. \t\t\tif (area < 2.8) return 'M';
  2039. \t\t\tif (area < 4.0) return 'L';
  2040. \t\t\treturn 'G';
  2041. \t\t}
  2042. \t\tfunction lookupSubsidyAmount(performance, sizeClass) {
  2043. \t\t\tif (!performance || !sizeClass) return 0;
  2044. \t\t\tvar t = WINDOW_SUBSIDY_MATRIX[getCurrentHousingKey()];
  2045. \t\t\tif (!t || !t[performance]) return 0;
  2046. \t\t\treturn t[performance][sizeClass] || 0;
  2047. \t\t}
  2048. \t\t/**
  2049. \t\t * mm 入力値を ladder バケット文字列に変換する.
  2050. \t\t *   bucketizeMm(1750, [\"100cm まで\",\"150cm まで\",\"200cm まで\",\"300cm まで\"]) → \"200cm まで\"
  2051. \t\t * - 入力が空 or 0 のときはそのまま返す (未入力扱い)
  2052. \t\t * - 入力がラダー最大を超えるときは最大バケットを返す (= 価格上限の保護)
  2053. \t\t * - 入力文字列が既にラダーラベルそのものなら無変換 (互換のため)
  2054. \t\t */
  2055. \t\tfunction bucketizeMm(input, ladder) {
  2056. \t\t\tif (!input && input !== 0) return '';
  2057. \t\t\tif (!ladder || ladder.length === 0) return input;
  2058. \t\t\tvar s = String(input).trim();
  2059. \t\t\tif (s === '') return '';
  2060. \t\t\tif (ladder.indexOf(s) >= 0) return s;
  2061. \t\t\tvar mm = parseMm(s);
  2062. \t\t\tif (mm <= 0) return s;
  2063. \t\t\tvar withMax = ladder.map(function(b) { return { label: b, max: parseMm(b) }; });
  2064. \t\t\twithMax.sort(function(a, b) { return a.max - b.max; });
  2065. \t\t\tfor (var i = 0; i < withMax.length; i++) {
  2066. \t\t\t\tif (mm <= withMax[i].max) return withMax[i].label;
  2067. \t\t\t}
  2068. \t\t\treturn withMax[withMax.length - 1].label;
  2069. \t\t}
  2070. \t\t/**
  2071. \t\t * pp 配列から該当 1 行を返す. 完全一致優先、見つからなければ最初の候補.
  2072. \t\t * 軸: subtype (option1) / w / h / m / c. axisMatch は既存ロジックと同じ.
  2073. \t\t * sale_type=2 では pw_val / ph_val に mm 数値が来るため、内部で bucketizeMm
  2074. \t\t * を通してから既存マッチングに渡す.
  2075. \t\t */
  2076. \t\tfunction lookupPpRow(subtype, pw_val, ph_val, pm_val, pc_val) {
  2077. \t\t\tif (!pp || pp.length === 0) return null;
  2078. \t\t\tvar pw_bucket = bucketizeMm(pw_val, PP_W_LADDER);
  2079. \t\t\tvar ph_bucket = bucketizeMm(ph_val, PP_H_LADDER);
  2080. \t\t\tvar axMatch = function(input, value) {
  2081. \t\t\t\treturn input == value || input === '指定なし' || value === '' || value == null;
  2082. \t\t\t};
  2083. \t\t\tvar colMatch = function(input, value) {
  2084. \t\t\t\tif (axMatch(input, value)) return true;
  2085. \t\t\t\tif (typeof value === 'string' && value.indexOf('/') !== -1 && input) {
  2086. \t\t\t\t\treturn value.split('/').some(function(s) { return s.trim() === input; });
  2087. \t\t\t\t}
  2088. \t\t\t\treturn false;
  2089. \t\t\t};
  2090. \t\t\tvar candidates = pp.filter(function(el) {
  2091. \t\t\t\treturn axMatch(pw_bucket, el.w)
  2092. \t\t\t\t\t&& axMatch(ph_bucket, el.h)
  2093. \t\t\t\t\t&& axMatch(pm_val, el.m)
  2094. \t\t\t\t\t&& axMatch(subtype, el.option1);
  2095. \t\t\t});
  2096. \t\t\tfor (var i = 0; i < candidates.length; i++) {
  2097. \t\t\t\tif (colMatch(pc_val, candidates[i].c)) return candidates[i];
  2098. \t\t\t}
  2099. \t\t\treturn candidates[0] || null;
  2100. \t\t}
  2101. \t\t/**
  2102. \t\t * \"1000mm\" / \"200cm\" / \"1.0m\" / 単位なし → mm に正規化して返す.
  2103. \t\t * UI 上の「200cm まで」等の文字列をそのまま渡せるようにする.
  2104. \t\t */
  2105. \t\tfunction parseMm(s) {
  2106. \t\t\tif (!s) return 0;
  2107. \t\t\tvar str = String(s);
  2108. \t\t\tvar m = str.match(/(\\d+(?:\\.\\d+)?)/);
  2109. \t\t\tif (!m) return 0;
  2110. \t\t\tvar num = parseFloat(m[1]);
  2111. \t\t\tif (/mm/i.test(str)) return num;
  2112. \t\t\tif (/cm/i.test(str)) return num * 10;
  2113. \t\t\tif (/(^|\\d)\\s*m(\$|\\W)/i.test(str)) return num * 1000;
  2114. \t\t\treturn num;
  2115. \t\t}
  2116. \t\t/**
  2117. \t\t * 1 タイプブロックから入力を読み、pp lookup → 単価・補助金額を計算して返す.
  2118. \t\t * incomplete=true: 軸のどれかが未選択 → 計算しない (UI で「未選択」を示すため).
  2119. \t\t */
  2120. \t\tfunction collectWindowTypeRow(block) {
  2121. \t\t\tvar get = function(axis) {
  2122. \t\t\t\t// radio / checkbox は :checked、それ以外 (number/text) は値そのまま.
  2123. \t\t\t\tvar radio = block.querySelector('input[data-axis=\"' + axis + '\"]:checked');
  2124. \t\t\t\tif (radio) return radio.value;
  2125. \t\t\t\tvar any = block.querySelector('input[data-axis=\"' + axis + '\"]');
  2126. \t\t\t\tif (!any) return '';
  2127. \t\t\t\tif (any.type === 'radio' || any.type === 'checkbox') return '';
  2128. \t\t\t\treturn (any.value || '').trim();
  2129. \t\t\t};
  2130. \t\t\tvar setqtyEl = block.querySelector('input[data-axis=\"setqty\"]');
  2131. \t\t\tvar subtype = get('subtype');
  2132. \t\t\tvar pw_val  = get('pw');
  2133. \t\t\tvar ph_val  = get('ph');
  2134. \t\t\tvar pm_val  = get('pm');
  2135. \t\t\tvar pc_val  = get('pc');
  2136. \t\t\tvar setqty  = setqtyEl ? Math.max(1, parseInt(setqtyEl.value) || 1) : 1;
  2137. \t\t\tvar row = {
  2138. \t\t\t\tsubtype: subtype, pw: pw_val, ph: ph_val, pm: pm_val, pc: pc_val, setqty: setqty,
  2139. \t\t\t\tunit_price_exc: 0, unit_ct_exc: 0, subsidy: 0,
  2140. \t\t\t\tsize_class: null, glass_perf: null,
  2141. \t\t\t\tincomplete: false
  2142. \t\t\t};
  2143. \t\t\t// p_option1 / p_w / p_h / p_m / color のいずれかが商品データに無いときは未選択でも完了扱いにする.
  2144. \t\t\t// (例: 商品によっては subtype が無い場合がある)
  2145. \t\t\tvar hasSubtype = !!block.querySelector('input[data-axis=\"subtype\"]');
  2146. \t\t\tvar hasPw      = !!block.querySelector('input[data-axis=\"pw\"]');
  2147. \t\t\tvar hasPh      = !!block.querySelector('input[data-axis=\"ph\"]');
  2148. \t\t\tvar hasPm      = !!block.querySelector('input[data-axis=\"pm\"]');
  2149. \t\t\tvar hasPc      = !!block.querySelector('input[data-axis=\"pc\"]');
  2150. \t\t\tif ((hasSubtype && !subtype) || (hasPw && !pw_val) || (hasPh && !ph_val)
  2151. \t\t\t    || (hasPm && !pm_val)  || (hasPc && !pc_val)) {
  2152. \t\t\t\trow.incomplete = true;
  2153. \t\t\t\treturn row;
  2154. \t\t\t}
  2155. \t\t\tvar ppRow = lookupPpRow(subtype, pw_val, ph_val, pm_val, pc_val);
  2156. \t\t\tif (ppRow) {
  2157. \t\t\t\trow.unit_price_exc = parseInt(ppRow.price) || 0;
  2158. \t\t\t\trow.unit_ct_exc    = parseInt(ppRow.ct)    || 0;
  2159. \t\t\t}
  2160. \t\t\t// ガラス名検出 → シリーズ上限 → subtype 上限 → 商品上限 の順で min クリップ.
  2161. \t\t\t// 例: LiteU (SERIES_GRADE_CAP_VAL=null) は Low-E でも null に落ちて補助対象外.
  2162. \t\t\t// 例: ウチリモの「内開き窓」subtype は真空ガラスでも S に落ちる.
  2163. \t\t\trow.glass_perf = finalizeGlassGrade(detectGlassPerformance(pm_val), subtype);
  2164. \t\t\trow.size_class = detectSizeClass(parseMm(pw_val), parseMm(ph_val));
  2165. \t\t\trow.subsidy    = lookupSubsidyAmount(row.glass_perf, row.size_class);
  2166. \t\t\treturn row;
  2167. \t\t}
  2168. \t\t/**
  2169. \t\t * sale_type=2 用集計: 全タイプから合計を出し DOM 更新.
  2170. \t\t * 計算式 (税抜→税込で出口で 1.10 倍):
  2171. \t\t *   商品金額 = Σ(各タイプ単価 × set_qty)
  2172. \t\t *   基本工事費 = 1 回分 (各タイプ pp.ct のうち最初に得た非ゼロ値)
  2173. \t\t *   補助金合計 = Σ(各タイプ補助金 × set_qty)
  2174. \t\t *   実質支払額 = (商品+ct+option) 税込 - 補助金合計
  2175. \t\t */
  2176. \t\tfunction recalcAllForSaleType2() {
  2177. \t\t\tif (typeof SALE_TYPE_ID === 'undefined' || SALE_TYPE_ID != 2) return;
  2178. \t\t\tif (!pp || pp.length === 0) {
  2179. \t\t\t\t\$('#mitsumori_message').text('価格データ準備中');
  2180. \t\t\t\t\$('#mitsumori_btn').hide();
  2181. \t\t\t\t['#mitsumori_goukei','#mitsumori_off','#mitsumori_price','#maker_price',
  2182. \t\t\t\t '#mitsumori_ct','#mitsumori_option','#mitsumori_kei','#mitsumori_shoukei','#mitsumori_tax']
  2183. \t\t\t\t .forEach(function(s){ \$(s).text('---円'); });
  2184. \t\t\t\treturn;
  2185. \t\t\t}
  2186. \t\t\tvar blocks = document.querySelectorAll('#window-types-container .window-type-block');
  2187. \t\t\tif (blocks.length === 0) return;
  2188. \t\t\tvar rows = [];
  2189. \t\t\tvar hasIncomplete = false;
  2190. \t\t\tvar baseCt = 0;
  2191. \t\t\tvar hasAnyPriced = false;
  2192. \t\t\tblocks.forEach(function(b) {
  2193. \t\t\t\tvar r = collectWindowTypeRow(b);
  2194. \t\t\t\trows.push({ block: b, row: r });
  2195. \t\t\t\tif (r.incomplete) hasIncomplete = true;
  2196. \t\t\t\tif (r.unit_ct_exc > 0 && baseCt === 0) baseCt = r.unit_ct_exc;
  2197. \t\t\t\tif (r.unit_price_exc > 0) hasAnyPriced = true;
  2198. \t\t\t\tvar subSpan = b.querySelector('.wt-subsidy-amount');
  2199. \t\t\t\tif (subSpan) subSpan.textContent = r.incomplete ? '―' : Math.round(r.subsidy * r.setqty).toLocaleString();
  2200. \t\t\t});
  2201. \t\t\tif (hasIncomplete || !hasAnyPriced) {
  2202. \t\t\t\t\$('#mitsumori_message').text('窓タイプを選択してください');
  2203. \t\t\t\t\$('#mitsumori_btn').hide();
  2204. \t\t\t\treturn;
  2205. \t\t\t}
  2206. \t\t\tvar ops = [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10];
  2207. \t\t\tvar purchaseOnly = ops.some(function(v){ return v === '商品購入のみ'; });
  2208. \t\t\tvar sumPriceExc = 0, sumSubsidy = 0, totalPanes = 0;
  2209. \t\t\trows.forEach(function(item) {
  2210. \t\t\t\tvar r = item.row;
  2211. \t\t\t\tsumPriceExc += r.unit_price_exc * r.setqty;
  2212. \t\t\t\tsumSubsidy  += r.subsidy * r.setqty;
  2213. \t\t\t\tif (r.unit_price_exc > 0) totalPanes += r.setqty;
  2214. \t\t\t});
  2215. \t\t\t// 内窓 工事費(顧客最終回答): 1枚目 22,000円 + 2枚目以降 1枚あたり +5,000円(税込表示額)。
  2216. \t\t\t// 既存パイプライン整合のため税抜(ctExc)も用意(税行 taxAmt 用)。商品購入のみは 0。
  2217. \t\t\tvar WINDOW_CT_BASE = 22000, WINDOW_CT_ADD = 5000;
  2218. \t\t\tvar ctIncTarget = purchaseOnly ? 0 : (WINDOW_CT_BASE + Math.max(0, totalPanes - 1) * WINDOW_CT_ADD);
  2219. \t\t\tvar ctExc  = purchaseOnly ? 0 : Math.round(ctIncTarget / (1 + TAX_RATE));
  2220. \t\t\tvar optExc = purchaseOnly ? 0 : (collectOptions().total || 0);
  2221. \t\t\tvar sumPriceInc = Math.round(sumPriceExc * (1 + TAX_RATE));
  2222. \t\t\tvar ctInc       = ctIncTarget;
  2223. \t\t\tvar optInc      = Math.round(optExc * (1 + TAX_RATE));
  2224. \t\t\tvar goukeiInc   = sumPriceInc + ctInc + optInc;
  2225. \t\t\t// 窓リノベ2026 申請条件:
  2226. \t\t\t//   - 補助金合計 ≥ 50,000 円 (5 万円未満は申請不可 → 還元 0 円扱い)
  2227. \t\t\t//   - 1 戸あたり上限 1,000,000 円 (住宅・非住宅240㎡以下)
  2228. \t\t\t//     ※ 非住宅 240㎡超の 10,000,000 円上限は対象外 (商品設計時に別扱い想定)
  2229. \t\t\tvar SUBSIDY_MIN_AMOUNT = 50000;
  2230. \t\t\tvar SUBSIDY_MAX_PER_UNIT = 1000000;
  2231. \t\t\tvar subsidyRawSum = sumSubsidy;
  2232. \t\t\tvar subsidyEligible = subsidyRawSum >= SUBSIDY_MIN_AMOUNT;
  2233. \t\t\tvar subsidyAmt = 0;
  2234. \t\t\tvar subsidyNote = '';
  2235. \t\t\tif (subsidyEligible) {
  2236. \t\t\t\tif (subsidyRawSum > SUBSIDY_MAX_PER_UNIT) {
  2237. \t\t\t\t\tsubsidyAmt = SUBSIDY_MAX_PER_UNIT;
  2238. \t\t\t\t\tsubsidyNote = '※補助上限 ' + SUBSIDY_MAX_PER_UNIT.toLocaleString()
  2239. \t\t\t\t\t\t+ '円 超過分は控除対象外(補助金合計 ' + subsidyRawSum.toLocaleString() + '円)';
  2240. \t\t\t\t} else {
  2241. \t\t\t\t\tsubsidyAmt = subsidyRawSum;
  2242. \t\t\t\t}
  2243. \t\t\t} else if (subsidyRawSum > 0) {
  2244. \t\t\t\tsubsidyNote = '※補助金合計が 5 万円未満のため申請対象外です('
  2245. \t\t\t\t\t+ subsidyRawSum.toLocaleString() + '円)';
  2246. \t\t\t} else if (SERIES_GRADE_CAP_VAL === null) {
  2247. \t\t\t\t// LiteU 等の単板構成シリーズ: グレード判定で必ず null になる
  2248. \t\t\t\tsubsidyNote = '※本商品は補助金(先進的窓リノベ2026事業)対象外です';
  2249. \t\t\t} else if (PRODUCT_GRADE_CAP === null) {
  2250. \t\t\t\tsubsidyNote = '※本商品は補助金対象外として登録されています';
  2251. \t\t\t}
  2252. \t\t\tvar implementedInc = Math.max(0, goukeiInc - subsidyAmt);
  2253. \t\t\tvar taxAmt      = Math.round((sumPriceExc + ctExc + optExc) * TAX_RATE);
  2254. \t\t\t\$('#mitsumori_message').text(subsidyNote);
  2255. \t\t\t\$('#mitsumori_btn').show();
  2256. \t\t\t\$('#mitsumori_goukei').text(goukeiInc.toLocaleString() + '円');
  2257. \t\t\t\$('#mitsumori_price').text(sumPriceInc.toLocaleString() + '円');
  2258. \t\t\t\$('#mitsumori_ct').text(ctInc.toLocaleString() + '円');
  2259. \t\t\t\$('#mitsumori_option').text(optInc.toLocaleString() + '円');
  2260. \t\t\t\$('#mitsumori_off').text((subsidyAmt > 0 ? '-' : '') + subsidyAmt.toLocaleString() + '円');
  2261. \t\t\t\$('#maker_price').text('---円'); // 補助金窓では未使用
  2262. \t\t\t\$('#mitsumori_kei').text(goukeiInc.toLocaleString() + '円');
  2263. \t\t\t\$('#mitsumori_shoukei').text(implementedInc.toLocaleString() + '円');
  2264. \t\t\t\$('#mitsumori_tax').text(taxAmt.toLocaleString() + '円');
  2265. \t\t\t// 内訳を mitsumori_json に詰めて hidden input にセット (PDF / カート連携用)
  2266. \t\t\tvar window_types = rows.map(function(item) {
  2267. \t\t\t\tvar r = item.row;
  2268. \t\t\t\t// 幅 / 高さは数値入力 (mm) が来るので \"1750mm\" 形式で保存する.
  2269. \t\t\t\t// 古い radio 由来の \"200cm まで\" 形式が来た場合はそのまま保存して互換.
  2270. \t\t\t\tvar w_mm = parseMm(r.pw);
  2271. \t\t\t\tvar h_mm = parseMm(r.ph);
  2272. \t\t\t\tvar w_save = (w_mm > 0 && /^\\s*\\d+(?:\\.\\d+)?\\s*\$/.test(String(r.pw))) ? (w_mm + 'mm') : r.pw;
  2273. \t\t\t\tvar h_save = (h_mm > 0 && /^\\s*\\d+(?:\\.\\d+)?\\s*\$/.test(String(r.ph))) ? (h_mm + 'mm') : r.ph;
  2274. \t\t\t\treturn {
  2275. \t\t\t\t\tsubtype:        r.subtype,
  2276. \t\t\t\t\tw:              w_save,
  2277. \t\t\t\t\th:              h_save,
  2278. \t\t\t\t\tglass:          r.pm,
  2279. \t\t\t\t\tcolor:          r.pc,
  2280. \t\t\t\t\tsetqty:         r.setqty,
  2281. \t\t\t\t\tunit_price_inc: Math.round(r.unit_price_exc * (1 + TAX_RATE)),
  2282. \t\t\t\t\tline_total_inc: Math.round(r.unit_price_exc * r.setqty * (1 + TAX_RATE)),
  2283. \t\t\t\t\tsize_class:     r.size_class,
  2284. \t\t\t\t\tglass_perf:     r.glass_perf,
  2285. \t\t\t\t\tsubsidy_unit:   r.subsidy,
  2286. \t\t\t\t\tsubsidy_total:  r.subsidy * r.setqty
  2287. \t\t\t\t};
  2288. \t\t\t});
  2289. \t\t\tvar opCalc2 = collectOptions();
  2290. \t\t\tvar mitsumori_json = {
  2291. \t\t\t\t\"mitsumori_goukei\": goukeiInc.toLocaleString() + '円',
  2292. \t\t\t\t\"mitsumori_price\":  sumPriceInc.toLocaleString() + '円',
  2293. \t\t\t\t\"mitsumori_ct\":     ctInc.toLocaleString() + '円',
  2294. \t\t\t\t\"mitsumori_option\": optInc.toLocaleString() + '円',
  2295. \t\t\t\t\"mitsumori_off\":    (subsidyAmt > 0 ? '-' : '') + subsidyAmt.toLocaleString() + '円',
  2296. \t\t\t\t\"maker_price\":      '---円',
  2297. \t\t\t\t\"product_id\":       ";
  2298.         // line 2154
  2299.         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'2154$this->source); })()), "id", [], "any"falsefalsefalse2154), "html"nulltrue);
  2300.         echo ",
  2301. \t\t\t\t\"sale_type\":        SALE_TYPE_ID,
  2302. \t\t\t\t\"housing_key\":      getCurrentHousingKey(),
  2303. \t\t\t\t\"series_key\":       DETECTED_SERIES,
  2304. \t\t\t\t\"series_grade_cap\": (SERIES_GRADE_CAP_VAL === undefined) ? null : SERIES_GRADE_CAP_VAL,
  2305. \t\t\t\t\"product_grade_cap\":(PRODUCT_GRADE_CAP    === undefined) ? null : PRODUCT_GRADE_CAP,
  2306. \t\t\t\t\"window_types\":     window_types,
  2307. \t\t\t\t\"subsidy_total\":    subsidyAmt,
  2308. \t\t\t\t\"subsidy_raw\":      subsidyRawSum,
  2309. \t\t\t\t\"subsidy_eligible\": subsidyEligible,
  2310. \t\t\t\t\"subsidy_note\":     subsidyNote,
  2311. \t\t\t\t\"op_items\":         opCalc2.items
  2312. \t\t\t};
  2313. \t\t\t\$('#mitsumori_json').val(JSON.stringify(mitsumori_json));
  2314. \t\t\trenderWindowTypesModalRows(window_types, subsidyAmt);
  2315. \t\t}
  2316. \t\t/**
  2317. \t\t * sale_type=2 用: 見積モーダル明細テーブルを window_types で動的展開.
  2318. \t\t * - 既存の商品名行 (1 行目) は hide() し、各タイプ行を上に挿入
  2319. \t\t * - 基本工事費行はそのまま (#mitsumori_ct_01 / _02 が更新されている)
  2320. \t\t * - 補助金 (割引額) 行を末尾に追加
  2321. \t\t * - 既存の renderOptionDetailRows と共存できるよう class で区別
  2322. \t\t */
  2323. \t\tfunction renderWindowTypesModalRows(window_types, subsidyAmt) {
  2324. \t\t\tvar \$tbody = \$('.modal-mitsumori table tbody');
  2325. \t\t\tif (!\$tbody.length) return;
  2326. \t\t\t// 既存の動的行を全削除 (opt-row は既存実装、wt-row / wt-subsidy-row は今回追加)
  2327. \t\t\t\$tbody.find('tr.wt-row, tr.wt-subsidy-row').remove();
  2328. \t\t\tvar \$itemRow = \$tbody.find('tr').first();
  2329. \t\t\tvar fmt = new Intl.NumberFormat('ja-JP');
  2330. \t\t\tif (!window_types || window_types.length === 0) {
  2331. \t\t\t\t// 集計対象なし → 商品名行を表示に戻す
  2332. \t\t\t\t\$itemRow.show();
  2333. \t\t\t\treturn;
  2334. \t\t\t}
  2335. \t\t\twindow_types.forEach(function(wt, i) {
  2336. \t\t\t\tvar label = '窓タイプ' + (i + 1) + ':'
  2337. \t\t\t\t\t+ (wt.subtype || '') + ' / '
  2338. \t\t\t\t\t+ (wt.w || '') + '×' + (wt.h || '') + ' / '
  2339. \t\t\t\t\t+ (wt.glass || '') + ' / '
  2340. \t\t\t\t\t+ (wt.color || '');
  2341. \t\t\t\tvar \$tr = \$('<tr class=\"wt-row\"></tr>')
  2342. \t\t\t\t\t.append('<td>' + label + '</td>')
  2343. \t\t\t\t\t.append('<td>' + wt.setqty + '</td>')
  2344. \t\t\t\t\t.append('<td>セット</td>')
  2345. \t\t\t\t\t.append('<td>' + fmt.format(wt.unit_price_inc) + '円</td>')
  2346. \t\t\t\t\t.append('<td>' + fmt.format(wt.line_total_inc) + '円</td>');
  2347. \t\t\t\t\$itemRow.before(\$tr);
  2348. \t\t\t});
  2349. \t\t\t// 元の商品名行は複数タイプに置換されたので非表示
  2350. \t\t\t\$itemRow.hide();
  2351. \t\t\t// 補助金(割引額)行を末尾に追加
  2352. \t\t\tif (subsidyAmt > 0) {
  2353. \t\t\t\tvar \$subRow = \$('<tr class=\"wt-subsidy-row\"></tr>')
  2354. \t\t\t\t\t.append('<td>補助金(割引額)</td>')
  2355. \t\t\t\t\t.append('<td>1</td>')
  2356. \t\t\t\t\t.append('<td>式</td>')
  2357. \t\t\t\t\t.append('<td>-' + fmt.format(subsidyAmt) + '円</td>')
  2358. \t\t\t\t\t.append('<td>-' + fmt.format(subsidyAmt) + '円</td>');
  2359. \t\t\t\t\$tbody.append(\$subRow);
  2360. \t\t\t}
  2361. \t\t}
  2362. \t\t// 公開: onWindowTypeAxisChange (UI 骨格 task 1) からも呼ばれる
  2363. \t\twindow.recalcAll = recalcAllForSaleType2;
  2364. \t\t// 公開: ガラス選択肢が補助金対象か (窓タイプブロック生成時のバッジ判定に使う).
  2365. \t\t// subtype は P→S に落とすことはあっても null にはしないため、性能区分の
  2366. \t\t// 対象/対象外は subtype に依存しない。ここでは series/product 上限のみ適用し、
  2367. \t\t// finalizeGlassGrade が null でなければ「補助金対象ガラス」と判定する。
  2368. \t\twindow.glassYieldsSubsidy = function(glassName) {
  2369. \t\t\tif (!glassName) return false;
  2370. \t\t\treturn finalizeGlassGrade(detectGlassPerformance(glassName), '') !== null;
  2371. \t\t};
  2372. \t\tfunction mitsumori_simulation(type , value_id){
  2373. \t\t\t// sale_type=2 (補助金窓) は複数タイプ集計 UI に統合済み. 既存 mitsumori_simulation は使わない.
  2374. \t\t\tif (typeof SALE_TYPE_ID !== 'undefined' && SALE_TYPE_ID == 2) {
  2375. \t\t\t\t// type/value_id が op\\d+ (施工オプション) の場合はグローバル変数を先に更新
  2376. \t\t\t\tif (type && /^op\\d+\$/.test(type) && value_id) {
  2377. \t\t\t\t\tvar v = \$('#'+value_id).val();
  2378. \t\t\t\t\tif (type === 'op0')  op0  = v;
  2379. \t\t\t\t\tif (type === 'op1')  op1  = v;
  2380. \t\t\t\t\tif (type === 'op2')  op2  = v;
  2381. \t\t\t\t\tif (type === 'op3')  op3  = v;
  2382. \t\t\t\t\tif (type === 'op4')  op4  = v;
  2383. \t\t\t\t\tif (type === 'op5')  op5  = v;
  2384. \t\t\t\t\tif (type === 'op6')  op6  = v;
  2385. \t\t\t\t\tif (type === 'op7')  op7  = v;
  2386. \t\t\t\t\tif (type === 'op8')  op8  = v;
  2387. \t\t\t\t\tif (type === 'op9')  op9  = v;
  2388. \t\t\t\t\tif (type === 'op10') op10 = v;
  2389. \t\t\t\t}
  2390. \t\t\t\trecalcAllForSaleType2();
  2391. \t\t\t\treturn;
  2392. \t\t\t}
  2393. \t\t\t// 価格データ未登録 (pp 行 0 件) の商品は axis 入力に依存せず
  2394. \t\t\t// 「価格データ準備中」を表示して終了する.
  2395. \t\t\t// (例: scrape 未対象の新規商品 — um のウチリモ 7487/7488 等)
  2396. \t\t\tif (!pp || pp.length === 0) {
  2397. \t\t\t\t\$('#mitsumori_message').text(\"価格データ準備中\");
  2398. \t\t\t\t\$('#mitsumori_btn').hide();
  2399. \t\t\t\t\$('#mitsumori_goukei').text(\"---円\");
  2400. \t\t\t\t\$('#mitsumori_off').text(\"---円\");
  2401. \t\t\t\t\$('#mitsumori_price').text(\"---円\");
  2402. \t\t\t\t\$('#maker_price').text(\"---円\");
  2403. \t\t\t\t\$('#mitsumori_ct').text(\"---円\");
  2404. \t\t\t\t\$('#mitsumori_option').text(\"---円\");
  2405. \t\t\t\t\$('#mitsumori_kei').text(\"---円\");
  2406. \t\t\t\t\$('#mitsumori_shoukei').text(\"---円\");
  2407. \t\t\t\t\$('#mitsumori_tax').text(\"---円\");
  2408. \t\t\t\treturn;
  2409. \t\t\t}
  2410. \t\t\tif(type == \"pw\"){
  2411. \t\t\t\tpw = \$('#'+value_id).val();
  2412. \t\t\t}
  2413. \t\t\tif(type == \"pd\"){
  2414. \t\t\t\tpd = \$('#'+value_id).val();
  2415. \t\t\t}
  2416. \t\t\tif(type == \"ph\"){
  2417. \t\t\t\tph = \$('#'+value_id).val();
  2418. \t\t\t}
  2419. \t\t\tif(type == \"pm\"){
  2420. \t\t\t\tpm = \$('#'+value_id).val();
  2421. \t\t\t}
  2422. \t\t\tif(type == \"pc\"){
  2423. \t\t\t\tpc = \$('#'+value_id).val();
  2424. \t\t\t}
  2425. \t\t\tif(type == \"option1\"){
  2426. \t\t\t\toption1 = \$('#'+value_id).val();
  2427. \t\t\t}
  2428. \t\t\tif(type == \"option2\"){
  2429. \t\t\t\toption2 = \$('#'+value_id).val();
  2430. \t\t\t}
  2431. \t\t\tif(type == \"op0\"){ op0 = \$('#'+value_id).val(); }
  2432. \t\t\tif(type == \"op1\"){ op1 = \$('#'+value_id).val(); }
  2433. \t\t\tif(type == \"op2\"){ op2 = \$('#'+value_id).val(); }
  2434. \t\t\tif(type == \"op3\"){ op3 = \$('#'+value_id).val(); }
  2435. \t\t\tif(type == \"op4\"){ op4 = \$('#'+value_id).val(); }
  2436. \t\t\tif(type == \"op5\"){ op5 = \$('#'+value_id).val(); }
  2437. \t\t\tif(type == \"op6\"){ op6 = \$('#'+value_id).val(); }
  2438. \t\t\tif(type == \"op7\"){ op7 = \$('#'+value_id).val(); }
  2439. \t\t\tif(type == \"op8\"){ op8 = \$('#'+value_id).val(); }
  2440. \t\t\tif(type == \"op9\"){ op9 = \$('#'+value_id).val(); }
  2441. \t\t\tif(type == \"op10\"){ op10 = \$('#'+value_id).val(); }
  2442. \t\t\t// op0 が「商品購入のみ」のとき、他のオプション (op1..op10) を disable 化.
  2443. \t\t\t// 価格計算側 (calcGoukei の purchaseOnly 分岐) は既にゼロ化しているが、
  2444. \t\t\t// UI で選択可能に見えるとユーザーが混乱するため radio を完全に無効化する.
  2445. \t\t\t(function applyPurchaseOnlyUI() {
  2446. \t\t\t\tvar isPurchaseOnly = (op0 === '商品購入のみ');
  2447. \t\t\t\tfor (var k = 1; k <= 10; k++) {
  2448. \t\t\t\t\tvar \$inputs = \$('input[name=\"op' + k + '\"]');
  2449. \t\t\t\t\tif (\$inputs.length === 0) continue;
  2450. \t\t\t\t\t\$inputs.prop('disabled', isPurchaseOnly);
  2451. \t\t\t\t\tvar \$group = \$inputs.first().closest('.form-group');
  2452. \t\t\t\t\t\$group.css({
  2453. \t\t\t\t\t\t'opacity':        isPurchaseOnly ? '0.4'  : '1',
  2454. \t\t\t\t\t\t'pointer-events': isPurchaseOnly ? 'none' : 'auto'
  2455. \t\t\t\t\t});
  2456. \t\t\t\t}
  2457. \t\t\t})();
  2458. \t\t\t// 全 type 共通: 該当 radio を checked にし、ボタンの is-selected を付け替え + ラベル更新.
  2459. \t\t\t//   value_id が指定されていて、対応する DOM 要素が opt-btn 配下にあれば適用する.
  2460. \t\t\t//   (icheck-danger 形式から opt-btn 形式に統一した際、option1/option2/pw/pd/ph/pm/pc 等の
  2461. \t\t\t//    クリックで is-selected が更新されない不具合があったため、op\\d+ 限定の処理を一般化)
  2462. \t\t\tif (value_id) {
  2463. \t\t\t\tvar \$clicked = \$('#' + value_id);
  2464. \t\t\t\tif (\$clicked.length && \$clicked.closest('.opt-btn').length) {
  2465. \t\t\t\t\t\$clicked.prop('checked', true);
  2466. \t\t\t\t\tvar groupName = \$clicked.attr('name');
  2467. \t\t\t\t\t\$('input[name=\"' + groupName + '\"]').closest('.opt-btn').removeClass('is-selected');
  2468. \t\t\t\t\t\$clicked.closest('.opt-btn').addClass('is-selected');
  2469. \t\t\t\t\tvar \$group = \$clicked.closest('.form-group');
  2470. \t\t\t\t\tvar \$label = \$group.find('.rp-section-label');
  2471. \t\t\t\t\tif (\$label.length) {
  2472. \t\t\t\t\t\tvar labelText = \$label.text().split(':')[0].trim();
  2473. \t\t\t\t\t\t\$label.html(labelText + ': <span>' + \$clicked.val() + '</span>');
  2474. \t\t\t\t\t}
  2475. \t\t\t\t\t// op_data の price=0 & 解体/撤去/設置場所 オプションの場合、ON 選択時に「現場調査後に正式お見積もり」文言を表示.
  2476. \t\t\t\t\t//   (twig 側で is_removal_unknown ブロックを描画済み。display 切替のみ JS で行う)
  2477. \t\t\t\t\tif (/^op\\d+\$/.test(type)) {
  2478. \t\t\t\t\t\tvar opIdx = type.replace('op', '');
  2479. \t\t\t\t\t\tvar opEntry = op_data[parseInt(opIdx)];
  2480. \t\t\t\t\t\tif (opEntry) {
  2481. \t\t\t\t\t\t\tvar \$note = \$group.find('.opt-survey-note[data-op-idx=\"' + opIdx + '\"]');
  2482. \t\t\t\t\t\t\tif (\$note.length) {
  2483. \t\t\t\t\t\t\t\tvar isOn = (\$clicked.val() === opEntry.on);
  2484. \t\t\t\t\t\t\t\t\$note.toggle(isOn);
  2485. \t\t\t\t\t\t\t}
  2486. \t\t\t\t\t\t}
  2487. \t\t\t\t\t\t// wd (sale_type=5) のステップ / デッキフェンス用の注記もここで切替.
  2488. \t\t\t\t\t\t//   ステップ → deck_step (op0 だが op_data 範囲外), 必要 選択時に表示.
  2489. \t\t\t\t\t\tvar radioName = \$clicked.attr('name');
  2490. \t\t\t\t\t\tif (radioName === 'deck_step') {
  2491. \t\t\t\t\t\t\t\$group.find('.opt-survey-note-wd-step').toggle(\$clicked.val() === '必要');
  2492. \t\t\t\t\t\t} else if (radioName === 'deck_fence') {
  2493. \t\t\t\t\t\t\t\$group.find('.opt-survey-note-wd-fence').toggle(\$clicked.val() === '必要');
  2494. \t\t\t\t\t\t}
  2495. \t\t\t\t\t}
  2496. \t\t\t\t}
  2497. \t\t\t}
  2498. \t\t\t// 必須項目チェックは sale_type 1 系(カーポート/物置/フェンスなど価格マトリクス必要)に限定
  2499. \t\t\tvar requireMatrix = (SALE_TYPE_ID == 1 || SALE_TYPE_ID == 2 || SALE_TYPE_ID == 3 || SALE_TYPE_ID == 4 || SALE_TYPE_ID == 5 || SALE_TYPE_ID == 6 || SALE_TYPE_ID == 7 || SALE_TYPE_ID == 9);
  2500. \t\t\t// sale_type=3 (物置・ゴミステーション・照明 等) では「素材」を選択肢として扱わない.
  2501. \t\t\t//   - mo/gs/sy は m が \"指定なし\" など名目的にしか入っていない
  2502. \t\t\t//   - sl は m が空のままで matrix に行が来る
  2503. \t\t\t//   そのため pm の必須チェックを sale_type=3 でスキップする。
  2504. \t\t\tvar pmRequired = (SALE_TYPE_ID != 3);
  2505. \t\t\tif (requireMatrix) {
  2506. \t\t\t\tif(pmRequired && pm == \"\"){
  2507. \t\t\t\t\t\$('#mitsumori_message').text(\"素材を選択してください\");
  2508. \t\t\t\t}
  2509. \t\t\t\tif(ph == \"\"){
  2510. \t\t\t\t\t\$('#mitsumori_message').text(\"高さを選択してください\");
  2511. \t\t\t\t}
  2512. \t\t\t\tif(pd == \"\"){
  2513. \t\t\t\t\t\$('#mitsumori_message').text(\"奥行きを選択してください\");
  2514. \t\t\t\t}
  2515. \t\t\t\tif(pw == \"\"){
  2516. \t\t\t\t\t\$('#mitsumori_message').text(\"幅を選択してください\");
  2517. \t\t\t\t}
  2518. \t\t\t\tif(pc == \"\"){
  2519. \t\t\t\t\t\$('#mitsumori_message').text(\"カラーを選択してください\");
  2520. \t\t\t\t\t\$('#mitsumori_btn').hide();
  2521. \t\t\t\t\t\$('#mitsumori_goukei').text(\"---円\");
  2522. \t\t\t\t\t\$('#mitsumori_off').text(\"---円\");
  2523. \t\t\t\t\t\$('#mitsumori_price').text(\"---円\");
  2524. \t\t\t\t\t\$('#maker_price').text(\"---円\");
  2525. \t\t\t\t\t\$('#mitsumori_ct').text(\"---円\");
  2526. \t\t\t\t\t\$('#mitsumori_option').text(\"---円\");
  2527. \t\t\t\t}
  2528. \t\t\t}
  2529. \t\t\tif(pw != \"\" && pd != \"\" && ph != \"\" && (!pmRequired || pm != \"\") && pc != \"\"){
  2530. \t\t\t\t\$('#mitsumori_btn').show();
  2531. \t\t\t\t// 入力コンテキスト(sale_type 別パラメータ)
  2532. \t\t\t\tvar ctx = {
  2533. \t\t\t\t\tset_count:    parseInt(\$('#set_count').val())    || 1,
  2534. \t\t\t\t\tdaisu:        parseInt(\$('#daisu').val())        || 1,
  2535. \t\t\t\t\tmaisu:        parseInt(\$('#maisu').val())        || 3,
  2536. \t\t\t\t\tsuuryou:      parseInt(\$('#suuryou').val())      || 1,
  2537. \t\t\t\t\tarea:         (function(){
  2538. \t\t\t\t\t\t// tf(人工芝): 施工サイズ 縦(m)×横(m) から面積を算出し #area に反映.
  2539. \t\t\t\t\t\tvar L = parseFloat(\$('#tf_len').val()) || 0;
  2540. \t\t\t\t\t\tvar W = parseFloat(\$('#tf_wid').val()) || 0;
  2541. \t\t\t\t\t\tif (L > 0 && W > 0) { var a = L * W; \$('#area').val(a); return a; }
  2542. \t\t\t\t\t\treturn parseFloat(\$('#area').val()) || 0;
  2543. \t\t\t\t\t})(),
  2544. \t\t\t\t\ttf_len:       parseFloat(\$('#tf_len').val())     || 0,
  2545. \t\t\t\t\ttf_wid:       parseFloat(\$('#tf_wid').val())     || 0,
  2546. \t\t\t\t\ttf_qty:       parseInt(\$('#tf_qty').val())       || 1,
  2547. \t\t\t\t\tquantityOnly: parseInt(\$('#quantity_only').val())|| 1,
  2548. \t\t\t\t\tmado_w:       \$('#mado_w').val() || '',
  2549. \t\t\t\t\tmado_h:       \$('#mado_h').val() || '',
  2550. \t\t\t\t\tmado_type:    \$('input[name=mado_type]:checked').val()  || '',
  2551. \t\t\t\t\tglass_type:   \$('input[name=glass_type]:checked').val() || '',
  2552. \t\t\t\t\tdeck_step:    \$('input[name=deck_step]:checked').val()  || '',
  2553. \t\t\t\t\tdeck_fence:   \$('input[name=deck_fence]:checked').val() || '',
  2554. \t\t\t\t};
  2555. \t\t\t\t// 施工オプション集計(残土処理を含む)
  2556. \t\t\t\tvar opCalc = collectOptions();
  2557. \t\t\t\tvar pp_matched = false;
  2558. \t\t\t\t// 各軸の汎用 axisMatch:
  2559. \t\t\t\t//   user 選択 == matrix 値 / user \"指定なし\" / matrix 値が空
  2560. \t\t\t\tvar axisMatch = function(input, value){
  2561. \t\t\t\t    return input == value || input == \"指定なし\" || value === \"\" || value == null;
  2562. \t\t\t\t};
  2563. \t\t\t\t// 色専用マッチャー: scraper のデータ形式に合わせて拡張する
  2564. \t\t\t\t//   1. 完全一致 / \"指定なし\" / 値が空 → 真 (axisMatch と同じ)
  2565. \t\t\t\t//   2. matrix 値が \"色1/色2/色3\" の形 (同価格グループ) → split して user 選択が含まれれば真
  2566. \t\t\t\t// scraper のロジック (scraper_price.py L765-779):
  2567. \t\t\t\t//   全色同価格 → c=\"\"、価格違いグループあり → 各 group を \"/\" 結合した色名で 1 行
  2568. \t\t\t\tvar colorMatch = function(input, value){
  2569. \t\t\t\t    if (axisMatch(input, value)) return true;
  2570. \t\t\t\t    if (typeof value === 'string' && value.indexOf('/') !== -1 && input) {
  2571. \t\t\t\t        var parts = value.split('/');
  2572. \t\t\t\t        for (var idx = 0; idx < parts.length; idx++) {
  2573. \t\t\t\t            if (parts[idx].trim() === input) return true;
  2574. \t\t\t\t        }
  2575. \t\t\t\t    }
  2576. \t\t\t\t    return false;
  2577. \t\t\t\t};
  2578. \t\t\t\t// 他軸 (w/d/h/m + option1/option2) でマッチする pp 行を抽出.
  2579. \t\t\t\t// option1/option2 は um の subtype 等で使われる. axisMatch は free_area 側が
  2580. \t\t\t\t// 空のとき真を返すので、um 以外のカテゴリ (option 軸を使わない) でも影響なし.
  2581. \t\t\t\tvar candidates = pp.filter(function(el){
  2582. \t\t\t\t    return axisMatch(pw, el.w) && axisMatch(pd, el.d) && axisMatch(ph, el.h) && axisMatch(pm, el.m)
  2583. \t\t\t\t        && axisMatch(option1, el.option1) && axisMatch(option2, el.option2);
  2584. \t\t\t\t});
  2585. \t\t\t\t// フォールバック: 全軸一致が 0 件のときに限り option1/option2 を無視して再マッチ。
  2586. \t\t\t\t// 玄関ドア等で option1(なし/ランマ付き)・option2(◯◯タイプ) が pm(開き方) から
  2587. \t\t\t\t// 導出可能な冗長軸で、未選択だと全軸 AND 一致を満たせず価格が出ない事象の救済。
  2588. \t\t\t\t// pm/幅/奥行/高さ は従来どおり一致を要求するため通常商品の価格選択に影響しない。
  2589. \t\t\t\tif (candidates.length === 0) {
  2590. \t\t\t\t    candidates = pp.filter(function(el){
  2591. \t\t\t\t        return axisMatch(pw, el.w) && axisMatch(pd, el.d) && axisMatch(ph, el.h) && axisMatch(pm, el.m);
  2592. \t\t\t\t    });
  2593. \t\t\t\t}
  2594. \t\t\t\tvar picked = null;
  2595. \t\t\t\t// 優先 1: 色も含めて完全一致 (\"色1/色2\" 形式の split match を含む)
  2596. \t\t\t\tfor (var ii = 0; ii < candidates.length; ii++) {
  2597. \t\t\t\t    if (colorMatch(pc, candidates[ii].c)) { picked = candidates[ii]; break; }
  2598. \t\t\t\t}
  2599. \t\t\t\t// 優先 2: 完全一致なし & user の pc が候補のどの c 値にも該当しない (= 命名違い等)
  2600. \t\t\t\t//   かつ候補全行で price が一致する場合は、色軸を実質無視して先頭行を採用.
  2601. \t\t\t\t//   例 id=3353: pp.c は \"ステンカラー+...\" 6種だが price は全て同じなので
  2602. \t\t\t\t//     SM(スミ) を選んでも安全に最初の行の価格を返せる.
  2603. \t\t\t\tif (!picked && candidates.length > 0) {
  2604. \t\t\t\t    var ppCsInCand = candidates.map(function(r){ return r.c || ''; });
  2605. \t\t\t\t    var pcAbsent = (pc !== '' && pc !== '指定なし' && ppCsInCand.indexOf(pc) === -1
  2606. \t\t\t\t                    && ppCsInCand.every(function(v){ return v.indexOf('/') === -1 || v.split('/').map(function(s){return s.trim();}).indexOf(pc) === -1; }));
  2607. \t\t\t\t    if (pcAbsent) {
  2608. \t\t\t\t        var uniqPrices = new Set();
  2609. \t\t\t\t        candidates.forEach(function(r){ uniqPrices.add(String(r.price)); });
  2610. \t\t\t\t        if (uniqPrices.size === 1) {
  2611. \t\t\t\t            // 全候補同価格 → 色軸を wildcard 扱いで OK
  2612. \t\t\t\t            picked = candidates[0];
  2613. \t\t\t\t        }
  2614. \t\t\t\t        // 価格が異なる場合は意図的に picked=null のまま「対応しておりません」.
  2615. \t\t\t\t    }
  2616. \t\t\t\t}
  2617. \t\t\t\tpp.forEach((el) => {
  2618. \t\t\t\t  if (el === picked) {
  2619. \t\t\t\t\tpp_matched = true;
  2620. \t\t\t\t\t// tg block-keyed オプション差額を集計 (tg 以外は total=0)
  2621. \t\t\t\t\tvar oiCalc = collectOptionItems(el.w || '', el.d || '');
  2622. \t\t\t\t\t// tg ブロックに合わせてラジオを再描画 (tg 以外は no-op)
  2623. \t\t\t\t\trenderOptionItemRadios(el.w || '', el.d || '');
  2624. \t\t\t\t\t// fe ブロックの種類×段数 サブ radio (fe 以外/未設定は no-op)
  2625. \t\t\t\t\trenderFeBlockRadios();
  2626. \t\t\t\t\t// fe ご希望のフェンス設置方法 — 「既存ブロックに穴空け」 entry の連動表示
  2627. \t\t\t\t\tupdateFeOpConditionalVisibility();
  2628. \t\t\t\t\tvar calc       = calcGoukei(el, opCalc.total, ctx);
  2629. \t\t\t\t\tvar goukei     = calc.goukei;
  2630. \t\t\t\t\tvar price      = calc.price;
  2631. \t\t\t\t\tvar ct         = calc.ct;
  2632. \t\t\t\t\tvar optionSum  = calc.opt;
  2633. \t\t\t\t\t// tf(人工芝): 必要枚数入力へ算出結果を反映(施工サイズ入力時は上書き、
  2634. \t\t\t\t\t// 直接指定時は同値なので実質変化なし。要素が無い sale_type では no-op)
  2635. \t\t\t\t\tvar \$tfQty = \$('#tf_qty');
  2636. \t\t\t\t\tif (\$tfQty.length) \$tfQty.val(calc.qty || 1);
  2637. \t\t\t\t\t// オプション差額は税抜 → 税込に変換して合計に加算
  2638. \t\t\t\t\tvar oiIncTax   = toIncTax(oiCalc.total);
  2639. \t\t\t\t\tgoukei += oiIncTax;
  2640. \t\t\t\t\tprice  += oiIncTax;  // 差額は本体価格扱いとして mitsumori_price にも加算
  2641. \t\t\t\t\t// maker_price も scraper が税抜で保存しているため税込に変換
  2642. \t\t\t\tvar makerPrice = toIncTax(parseInt(el.maker_price) || 0);
  2643. \t\t\t\t\t\$('#mitsumori_message').text(formatter.format(goukei) + \"円\");
  2644. \t\t\t\t\t\$('#mitsumori_goukei').text(formatter.format(goukei) + \"円\");
  2645. \t\t\t\t\t\$('#mitsumori_off').text(formatter.format(price - makerPrice) + \"円\");
  2646. \t\t\t\t\t\$('#mitsumori_price').text(formatter.format(price) + \"円\");
  2647. \t\t\t\t\t\$('#maker_price').text(formatter.format(makerPrice) + \"円\");
  2648. \t\t\t\t\t\$('#mitsumori_ct').text(formatter.format(ct) + \"円\");
  2649. \t\t\t\t\t\$('#mitsumori_option').text(formatter.format(optionSum) + \"円\");
  2650. \t\t\t\t\t\$('#mitsumori_kei').text(formatter.format(goukei) + \"円\");
  2651. \t\t\t\t\t\$('#mitsumori_price_01').text(formatter.format(price) + \"円\");
  2652. \t\t\t\t\t\$('#mitsumori_price_02').text(formatter.format(price) + \"円\");
  2653. \t\t\t\t\t\$('#mitsumori_ct_01').text(formatter.format(ct) + \"円\");
  2654. \t\t\t\t\t\$('#mitsumori_ct_02').text(formatter.format(ct) + \"円\");
  2655. \t\t\t\t\t\$('#mitsumori_goukei_02').text(formatter.format(goukei) + \"円\");
  2656. \t\t\t\t\tvar shoukei = goukei / 1.1;
  2657. \t\t\t\t\tvar tax     = parseInt(goukei - shoukei);
  2658. \t\t\t\t\t\$('#mitsumori_shoukei').text(formatter.format(parseInt(shoukei)) + \"円\");
  2659. \t\t\t\t\t\$('#mitsumori_tax').text(formatter.format(tax) + \"円\");
  2660. \t\t\t\t\t// PDF 明細用:オプション内訳テーブルを差し込む (施工オプション + tg block オプション)
  2661. \t\t\t\t\trenderOptionDetailRows(opCalc.items.concat(oiCalc.items.map(function(it){
  2662. \t\t\t\t\t\treturn { name: it.name, value: it.label, price: it.diff };
  2663. \t\t\t\t\t})));
  2664. \t\t\t\t  }
  2665. \t\t\t\t});
  2666. \t\t\t\tif (!pp_matched) {
  2667. \t\t\t\t\t\$('#mitsumori_message').text(\"この組み合わせは対応しておりません\");
  2668. \t\t\t\t\t\$('#mitsumori_btn').hide();
  2669. \t\t\t\t\t\$('#mitsumori_goukei').text(\"---円\");
  2670. \t\t\t\t\t\$('#mitsumori_off').text(\"---円\");
  2671. \t\t\t\t\t\$('#mitsumori_price').text(\"---円\");
  2672. \t\t\t\t\t\$('#maker_price').text(\"---円\");
  2673. \t\t\t\t\t\$('#mitsumori_ct').text(\"---円\");
  2674. \t\t\t\t\t\$('#mitsumori_option').text(\"---円\");
  2675. \t\t\t\t\t\$('#mitsumori_kei').text(\"---円\");
  2676. \t\t\t\t\t\$('#mitsumori_shoukei').text(\"---円\");
  2677. \t\t\t\t\t\$('#mitsumori_tax').text(\"---円\");
  2678. \t\t\t\t}
  2679. \t\t\t\t// mitsumori_json: バック側に送信する見積データ
  2680. \t\t\t\tvar mitsumori_json = { \"mitsumori_goukei\": \$('#mitsumori_goukei').text(),
  2681. \t\t\t\t\t\t\t\t\t\t\"mitsumori_goukei_02\": \$('#mitsumori_goukei_02').text(),
  2682. \t\t\t\t\t\t\t\t\t\t\"mitsumori_price\": \$('#mitsumori_price').text(),
  2683. \t\t\t\t\t\t\t\t\t\t\"maker_price\": \$('#maker_price').text(),
  2684. \t\t\t\t\t\t\t\t\t\t\"mitsumori_off\": \$('#mitsumori_off').text(),
  2685. \t\t\t\t\t\t\t\t\t\t\"mitsumori_ct\": \$('#mitsumori_ct').text(),
  2686. \t\t\t\t\t\t\t\t\t\t\"mitsumori_option\": \$('#mitsumori_option').text(),
  2687. \t\t\t\t\t\t\t\t\t\t\"product_id\": ";
  2688.         // line 2571
  2689.         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'2571$this->source); })()), "id", [], "any"falsefalsefalse2571), "html"nulltrue);
  2690.         echo ",
  2691. \t\t\t\t\t\t\t\t\t\t\"sale_type\": SALE_TYPE_ID,
  2692. \t\t\t\t\t\t\t\t\t\t\"pw\": pw,
  2693. \t\t\t\t\t\t\t\t\t\t\"pd\": pd,
  2694. \t\t\t\t\t\t\t\t\t\t\"ph\": ph,
  2695. \t\t\t\t\t\t\t\t\t\t\"pm\": pm,
  2696. \t\t\t\t\t\t\t\t\t\t\"pc\": pc,
  2697. \t\t\t\t\t\t\t\t\t\t\"op\": [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10],
  2698. \t\t\t\t\t\t\t\t\t\t\"op_items\": opCalc.items,
  2699. \t\t\t\t\t\t\t\t\t\t\"mado_w\":     ctx.mado_w,
  2700. \t\t\t\t\t\t\t\t\t\t\"mado_h\":     ctx.mado_h,
  2701. \t\t\t\t\t\t\t\t\t\t\"mado_type\":  ctx.mado_type,
  2702. \t\t\t\t\t\t\t\t\t\t\"glass_type\": ctx.glass_type,
  2703. \t\t\t\t\t\t\t\t\t\t\"set_count\":  ctx.set_count,
  2704. \t\t\t\t\t\t\t\t\t\t\"daisu\":      ctx.daisu,
  2705. \t\t\t\t\t\t\t\t\t\t\"maisu\":      ctx.maisu,
  2706. \t\t\t\t\t\t\t\t\t\t\"suuryou\":    ctx.suuryou,
  2707. \t\t\t\t\t\t\t\t\t\t\"area\":       ctx.area,
  2708. \t\t\t\t\t\t\t\t\t\t\"tf_len\":     ctx.tf_len,
  2709. \t\t\t\t\t\t\t\t\t\t\"tf_wid\":     ctx.tf_wid,
  2710. \t\t\t\t\t\t\t\t\t\t\"tf_qty\":     \$('#tf_qty').val(),
  2711. \t\t\t\t\t\t\t\t\t\t\"deck_step\":  ctx.deck_step,
  2712. \t\t\t\t\t\t\t\t\t\t\"deck_fence\": ctx.deck_fence };
  2713. \t\t\t\t\$('#mitsumori_json').val(JSON.stringify(mitsumori_json));
  2714. \t\t\t}
  2715. \t\t}
  2716. \t\t// PDF/モーダル明細の動的差し替え(基本工事費の次にオプション行を追加)
  2717. \t\tfunction renderOptionDetailRows(items) {
  2718. \t\t\tvar \$tbody = \$('.modal-mitsumori table tbody');
  2719. \t\t\tif (!\$tbody.length) return;
  2720. \t\t\t\$tbody.find('tr.opt-row').remove();
  2721. \t\t\tvar anchorRow = \$tbody.find('tr').filter(function(){
  2722. \t\t\t\treturn \$(this).find('td:first').text().indexOf('残土') !== -1
  2723. \t\t\t\t\t|| \$(this).find('td:first').text().indexOf('基本工事費') !== -1;
  2724. \t\t\t}).last();
  2725. \t\t\titems.forEach(function(it){
  2726. \t\t\t\tif (!it.name || !it.value) return;
  2727. \t\t\t\tvar priceTxt = it.price > 0
  2728. \t\t\t\t\t? formatter.format(it.price) + '円'
  2729. \t\t\t\t\t: '0円';
  2730. \t\t\t\tvar \$tr = \$('<tr class=\"opt-row\"></tr>')
  2731. \t\t\t\t\t.append('<td>' + it.name + ':' + it.value + '</td>')
  2732. \t\t\t\t\t.append('<td>1</td>')
  2733. \t\t\t\t\t.append('<td>式</td>')
  2734. \t\t\t\t\t.append('<td>' + priceTxt + '</td>')
  2735. \t\t\t\t\t.append('<td>' + (it.price > 0 ? formatter.format(it.price) + '円' : '') + '</td>');
  2736. \t\t\t\tif (anchorRow.length) {
  2737. \t\t\t\t\tanchorRow.after(\$tr);
  2738. \t\t\t\t\tanchorRow = \$tr;
  2739. \t\t\t\t} else {
  2740. \t\t\t\t\t\$tbody.append(\$tr);
  2741. \t\t\t\t}
  2742. \t\t\t});
  2743. \t\t}
  2744. \t\t// 見積書モーダルを開く直前に、右側「現在のお見積り額」パネルの表示値を
  2745. \t\t// モーダル内の対応 ID にコピーして金額の食い違いを防ぐ。
  2746. \t\t// pw/pd/ph/pm が未選択で mitsumori_simulation の full update に到達しない場合でも、
  2747. \t\t// パネル側の値(HTML 静的初期値 or 直近の simulation 結果)が modal にも反映される。
  2748. \t\tfunction syncMitsumoriModalFromPanel() {
  2749. \t\t\tvar goukeiText = \$('#mitsumori_goukei').text();
  2750. \t\t\tvar priceText  = \$('#mitsumori_price').text();
  2751. \t\t\tvar ctText     = \$('#mitsumori_ct').text();
  2752. \t\t\t\$('#mitsumori_kei').text(goukeiText);
  2753. \t\t\t\$('#mitsumori_price_01').text(priceText);
  2754. \t\t\t\$('#mitsumori_price_02').text(priceText);
  2755. \t\t\t\$('#mitsumori_ct_01').text(ctText);
  2756. \t\t\t\$('#mitsumori_ct_02').text(ctText);
  2757. \t\t\t\$('#mitsumori_goukei_02').text(goukeiText);
  2758. \t\t\t// 小計 / 消費税 は税込 goukei から逆算
  2759. \t\t\tvar num = parseInt(goukeiText.replace(/[^\\d-]/g, ''), 10);
  2760. \t\t\tif (!isNaN(num) && num > 0) {
  2761. \t\t\t\tvar shoukei = Math.round(num / 1.1);
  2762. \t\t\t\tvar tax     = num - shoukei;
  2763. \t\t\t\t\$('#mitsumori_shoukei').text(formatter.format(shoukei) + '円');
  2764. \t\t\t\t\$('#mitsumori_tax').text(formatter.format(tax) + '円');
  2765. \t\t\t} else {
  2766. \t\t\t\t\$('#mitsumori_shoukei').text('---円');
  2767. \t\t\t\t\$('#mitsumori_tax').text('---円');
  2768. \t\t\t}
  2769. \t\t}
  2770. \t\t\$(document).on('show.bs.modal', '#modal-mitsumori', function () {
  2771. \t\t\tsyncMitsumoriModalFromPanel();
  2772. \t\t});
  2773.         ";
  2774.         // line 2665
  2775.         echo "        ";
  2776.         if (((isset($context["p_c"]) || array_key_exists("p_c"$context) ? $context["p_c"] : (function () { throw new RuntimeError('Variable "p_c" does not exist.'2665$this->source); })()) && ((twig_length_filter($this->env, (isset($context["p_c"]) || array_key_exists("p_c"$context) ? $context["p_c"] : (function () { throw new RuntimeError('Variable "p_c" does not exist.'2665$this->source); })())) == 1) || (twig_join_filter((isset($context["p_c"]) || array_key_exists("p_c"$context) ? $context["p_c"] : (function () { throw new RuntimeError('Variable "p_c" does not exist.'2665$this->source); })())) == "")))) {
  2777.             // line 2666
  2778.             echo "            pc = \"指定なし\";
  2779.             ";
  2780.             // line 2667
  2781.             $context['_parent'] = $context;
  2782.             $context['_seq'] = twig_ensure_traversable((isset($context["p_c"]) || array_key_exists("p_c"$context) ? $context["p_c"] : (function () { throw new RuntimeError('Variable "p_c" does not exist.'2667$this->source); })()));
  2783.             foreach ($context['_seq'] as $context["_key"] => $context["pc_val"]) {
  2784.                 if ($context["pc_val"]) {
  2785.                     echo " pc = \"";
  2786.                     echo twig_escape_filter($this->env$context["pc_val"], "html"nulltrue);
  2787.                     echo "\"; ";
  2788.                 }
  2789.             }
  2790.             $_parent $context['_parent'];
  2791.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pc_val'], $context['_parent'], $context['loop']);
  2792.             $context array_intersect_key($context$_parent) + $_parent;
  2793.             // line 2668
  2794.             echo "            ";
  2795.             if (((isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'2668$this->source); })()) && (twig_length_filter($this->env, (isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'2668$this->source); })())) == 1))) {
  2796.                 // line 2669
  2797.                 echo "                ";
  2798.                 $context['_parent'] = $context;
  2799.                 $context['_seq'] = twig_ensure_traversable((isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'2669$this->source); })()));
  2800.                 foreach ($context['_seq'] as $context["_key"] => $context["cc"]) {
  2801.                     if (($context["cc"] && twig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse2669))) {
  2802.                         echo " pc = \"";
  2803.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse2669), "html"nulltrue);
  2804.                         echo "\"; ";
  2805.                     }
  2806.                 }
  2807.                 $_parent $context['_parent'];
  2808.                 unset($context['_seq'], $context['_iterated'], $context['_key'], $context['cc'], $context['_parent'], $context['loop']);
  2809.                 $context array_intersect_key($context$_parent) + $_parent;
  2810.                 // line 2670
  2811.                 echo "            ";
  2812.             }
  2813.             // line 2671
  2814.             echo "        ";
  2815.         } elseif (((isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'2671$this->source); })()) && (twig_length_filter($this->env, (isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'2671$this->source); })())) == 1))) {
  2816.             // line 2672
  2817.             echo "            pc = \"指定なし\";
  2818. \t\t\t";
  2819.             // line 2673
  2820.             $context['_parent'] = $context;
  2821.             $context['_seq'] = twig_ensure_traversable((isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'2673$this->source); })()));
  2822.             foreach ($context['_seq'] as $context["_key"] => $context["cc"]) {
  2823.                 if (($context["cc"] && twig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse2673))) {
  2824.                     echo " pc = \"";
  2825.                     echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse2673), "html"nulltrue);
  2826.                     echo "\"; ";
  2827.                 }
  2828.             }
  2829.             $_parent $context['_parent'];
  2830.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['cc'], $context['_parent'], $context['loop']);
  2831.             $context array_intersect_key($context$_parent) + $_parent;
  2832.             // line 2674
  2833.             echo "\t\t";
  2834.         }
  2835.         // line 2675
  2836.         echo "
  2837.         ";
  2838.         // line 2676
  2839.         if (((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'2676$this->source); })()) && ((twig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'2676$this->source); })())) == 1) || (twig_join_filter((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'2676$this->source); })())) == "")))) {
  2840.             // line 2677
  2841.             echo "            pw = \"指定なし\";
  2842. \t\t\t";
  2843.             // line 2678
  2844.             $context['_parent'] = $context;
  2845.             $context['_seq'] = twig_ensure_traversable((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'2678$this->source); })()));
  2846.             foreach ($context['_seq'] as $context["_key"] => $context["pw"]) {
  2847.                 if ($context["pw"]) {
  2848.                     echo " pw = \"";
  2849.                     echo twig_escape_filter($this->env$context["pw"], "html"nulltrue);
  2850.                     echo "\"; ";
  2851.                 }
  2852.             }
  2853.             $_parent $context['_parent'];
  2854.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pw'], $context['_parent'], $context['loop']);
  2855.             $context array_intersect_key($context$_parent) + $_parent;
  2856.             // line 2679
  2857.             echo "\t\t";
  2858.         }
  2859.         // line 2680
  2860.         echo "
  2861.         ";
  2862.         // line 2681
  2863.         if (((isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'2681$this->source); })()) && ((twig_length_filter($this->env, (isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'2681$this->source); })())) == 1) || (twig_join_filter((isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'2681$this->source); })())) == "")))) {
  2864.             // line 2682
  2865.             echo "            pd = \"指定なし\";
  2866. \t\t\t";
  2867.             // line 2683
  2868.             $context['_parent'] = $context;
  2869.             $context['_seq'] = twig_ensure_traversable((isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'2683$this->source); })()));
  2870.             foreach ($context['_seq'] as $context["_key"] => $context["pd"]) {
  2871.                 if ($context["pd"]) {
  2872.                     echo " pd = \"";
  2873.                     echo twig_escape_filter($this->env$context["pd"], "html"nulltrue);
  2874.                     echo "\"; ";
  2875.                 }
  2876.             }
  2877.             $_parent $context['_parent'];
  2878.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pd'], $context['_parent'], $context['loop']);
  2879.             $context array_intersect_key($context$_parent) + $_parent;
  2880.             // line 2684
  2881.             echo "\t\t";
  2882.         }
  2883.         // line 2685
  2884.         echo "
  2885.         ";
  2886.         // line 2686
  2887.         if (((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'2686$this->source); })()) && ((twig_length_filter($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'2686$this->source); })())) == 1) || (twig_join_filter((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'2686$this->source); })())) == "")))) {
  2888.             // line 2687
  2889.             echo "            ph = \"指定なし\";
  2890. \t\t\t";
  2891.             // line 2688
  2892.             $context['_parent'] = $context;
  2893.             $context['_seq'] = twig_ensure_traversable((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'2688$this->source); })()));
  2894.             foreach ($context['_seq'] as $context["_key"] => $context["ph"]) {
  2895.                 if ($context["ph"]) {
  2896.                     echo " ph = \"";
  2897.                     echo twig_escape_filter($this->env$context["ph"], "html"nulltrue);
  2898.                     echo "\"; ";
  2899.                 }
  2900.             }
  2901.             $_parent $context['_parent'];
  2902.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['ph'], $context['_parent'], $context['loop']);
  2903.             $context array_intersect_key($context$_parent) + $_parent;
  2904.             // line 2689
  2905.             echo "\t\t";
  2906.         }
  2907.         // line 2690
  2908.         echo "
  2909.         ";
  2910.         // line 2691
  2911.         if (((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'2691$this->source); })()) && ((twig_length_filter($this->env, (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'2691$this->source); })())) == 1) || (twig_join_filter((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'2691$this->source); })())) == "")))) {
  2912.             // line 2692
  2913.             echo "            pm = \"指定なし\";
  2914. \t\t\t";
  2915.             // line 2693
  2916.             $context['_parent'] = $context;
  2917.             $context['_seq'] = twig_ensure_traversable((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'2693$this->source); })()));
  2918.             foreach ($context['_seq'] as $context["_key"] => $context["pm"]) {
  2919.                 if ($context["pm"]) {
  2920.                     echo " pm = \"";
  2921.                     echo twig_escape_filter($this->env$context["pm"], "html"nulltrue);
  2922.                     echo "\"; ";
  2923.                 }
  2924.             }
  2925.             $_parent $context['_parent'];
  2926.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pm'], $context['_parent'], $context['loop']);
  2927.             $context array_intersect_key($context$_parent) + $_parent;
  2928.             // line 2694
  2929.             echo "\t\t";
  2930.         }
  2931.         // line 2695
  2932.         echo "
  2933.         ";
  2934.         // line 2697
  2935.         echo "        ";
  2936.         if (((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'2697$this->source); })()) && ((twig_length_filter($this->env, (isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'2697$this->source); })())) == 1) || (twig_join_filter((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'2697$this->source); })())) == "")))) {
  2937.             // line 2698
  2938.             echo "            option1 = \"\";
  2939. \t\t\t";
  2940.             // line 2699
  2941.             $context['_parent'] = $context;
  2942.             $context['_seq'] = twig_ensure_traversable((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'2699$this->source); })()));
  2943.             foreach ($context['_seq'] as $context["_key"] => $context["opt1"]) {
  2944.                 if ($context["opt1"]) {
  2945.                     echo " option1 = \"";
  2946.                     echo twig_escape_filter($this->envtwig_escape_filter($this->env$context["opt1"], "js"), "html"nulltrue);
  2947.                     echo "\"; ";
  2948.                 }
  2949.             }
  2950.             $_parent $context['_parent'];
  2951.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['opt1'], $context['_parent'], $context['loop']);
  2952.             $context array_intersect_key($context$_parent) + $_parent;
  2953.             // line 2700
  2954.             echo "\t\t";
  2955.         }
  2956.         // line 2701
  2957.         echo "
  2958.         ";
  2959.         // line 2702
  2960.         if (((isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'2702$this->source); })()) && ((twig_length_filter($this->env, (isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'2702$this->source); })())) == 1) || (twig_join_filter((isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'2702$this->source); })())) == "")))) {
  2961.             // line 2703
  2962.             echo "            option2 = \"\";
  2963. \t\t\t";
  2964.             // line 2704
  2965.             $context['_parent'] = $context;
  2966.             $context['_seq'] = twig_ensure_traversable((isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'2704$this->source); })()));
  2967.             foreach ($context['_seq'] as $context["_key"] => $context["opt2"]) {
  2968.                 if ($context["opt2"]) {
  2969.                     echo " option2 = \"";
  2970.                     echo twig_escape_filter($this->envtwig_escape_filter($this->env$context["opt2"], "js"), "html"nulltrue);
  2971.                     echo "\"; ";
  2972.                 }
  2973.             }
  2974.             $_parent $context['_parent'];
  2975.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['opt2'], $context['_parent'], $context['loop']);
  2976.             $context array_intersect_key($context$_parent) + $_parent;
  2977.             // line 2705
  2978.             echo "\t\t";
  2979.         }
  2980.         // line 2706
  2981.         echo "
  2982. \t\t// カラー radio が複数あるとき初期チェックが無いと「カラーを選択してください」固定になるので、
  2983. \t\t// 何もチェックされていなければ「最初の radio」を選択する。
  2984. \t\t// sale_type≠3 は name=\"color\", sale_type=3 は name=\"color3\".
  2985. \t\t//
  2986. \t\t// 注意:
  2987. \t\t//   ・search_word(= radio の値)と pp.c(= matrix の色軸)は別の命名体系のケースがある
  2988. \t\t//     (例 id=3353: radio=\"SM(スミ)\" / pp.c=\"ステンカラー+セピアブラウン\")
  2989. \t\t//   ・pp.c に合わせて radio を選ぼうとしても文字列一致しないので無意味。
  2990. \t\t//   ・単純に「先頭の radio」を選ぶ実装に戻し、マッチング側で命名体系違いを吸収する
  2991. \t\t//     (pc が pp.c のどの値にもマッチしないときは色軸を wildcard 扱いにする)。
  2992. \t\t//   ・.rp-section-label のテキストも忘れずに同期する(古い session 値が残ると
  2993. \t\t//     \"ステンカラー+セピアブラウン\" のような表示と実際の radio が食い違う)。
  2994. \t\t(function autoSelectFirstColor(){
  2995. \t\t\tvar groups = ['color', 'color3'];
  2996. \t\t\tfor (var gi = 0; gi < groups.length; gi++) {
  2997. \t\t\t\tvar name = groups[gi];
  2998. \t\t\t\tvar nodes = document.querySelectorAll('input[type=\"radio\"][name=\"' + name + '\"]');
  2999. \t\t\t\tif (nodes.length === 0) continue;
  3000. \t\t\t\tvar anyChecked = false;
  3001. \t\t\t\tfor (var i = 0; i < nodes.length; i++) {
  3002. \t\t\t\t\tif (nodes[i].checked) { anyChecked = true; break; }
  3003. \t\t\t\t}
  3004. \t\t\t\tif (anyChecked) continue;
  3005. \t\t\t\tvar target = nodes[0];
  3006. \t\t\t\ttarget.checked = true;
  3007. \t\t\t\tpc = target.value;
  3008. \t\t\t\t// opt-btn の is-selected を付け替え
  3009. \t\t\t\tvar lbl = target.closest('.opt-btn');
  3010. \t\t\t\tif (lbl) {
  3011. \t\t\t\t\tvar sib = lbl.parentNode ? lbl.parentNode.querySelectorAll('.opt-btn') : [];
  3012. \t\t\t\t\tfor (var k = 0; k < sib.length; k++) sib[k].classList.remove('is-selected');
  3013. \t\t\t\t\tlbl.classList.add('is-selected');
  3014. \t\t\t\t}
  3015. \t\t\t\t// 「カラー: <name>」表示の同期(古い mitsumori_json.pc が残らないように)
  3016. \t\t\t\tvar grp = (lbl && lbl.closest('.form-group')) || (target.closest('.form-group'));
  3017. \t\t\t\tif (grp) {
  3018. \t\t\t\t\tvar section = grp.querySelector('.rp-section-label');
  3019. \t\t\t\t\tif (section) {
  3020. \t\t\t\t\t\tvar labelHead = section.textContent.split(':')[0].trim();
  3021. \t\t\t\t\t\tsection.innerHTML = labelHead + ': <span>' + target.value + '</span>';
  3022. \t\t\t\t\t}
  3023. \t\t\t\t}
  3024. \t\t\t}
  3025. \t\t})();
  3026. \t\t// option1 / option2 / pw / pd / ph / pm (matrix 軸の radio 群) も同様に
  3027. \t\t// 「どれもチェックされていなければ先頭を選ぶ」を適用する.
  3028. \t\t//   sale_type=2 の窓タイプ等で「初期表示時に一番初めの選択肢が選択されていない」事象を解消.
  3029. \t\t(function autoSelectFirstMatrixAxis(){
  3030. \t\t\tvar axes = [
  3031. \t\t\t\t{ name: 'pw',      jsVar: 'pw' },
  3032. \t\t\t\t{ name: 'pd',      jsVar: 'pd' },
  3033. \t\t\t\t{ name: 'ph',      jsVar: 'ph' },
  3034. \t\t\t\t{ name: 'pm',      jsVar: 'pm' },
  3035. \t\t\t\t{ name: 'glass_type', jsVar: 'pm' },
  3036. \t\t\t\t{ name: 'option1', jsVar: 'option1' },
  3037. \t\t\t\t{ name: 'option2', jsVar: 'option2' }
  3038. \t\t\t];
  3039. \t\t\tfor (var ai = 0; ai < axes.length; ai++) {
  3040. \t\t\t\tvar ax = axes[ai];
  3041. \t\t\t\tvar nodes = document.querySelectorAll('input[type=\"radio\"][name=\"' + ax.name + '\"]');
  3042. \t\t\t\tif (nodes.length === 0) continue;
  3043. \t\t\t\tvar anyChecked = false;
  3044. \t\t\t\tfor (var i = 0; i < nodes.length; i++) {
  3045. \t\t\t\t\tif (nodes[i].checked) { anyChecked = true; break; }
  3046. \t\t\t\t}
  3047. \t\t\t\tif (anyChecked) continue;
  3048. \t\t\t\tvar target = nodes[0];
  3049. \t\t\t\ttarget.checked = true;
  3050. \t\t\t\t// グローバル JS 変数も埋める
  3051. \t\t\t\tif (ax.jsVar === 'pw') pw = target.value;
  3052. \t\t\t\telse if (ax.jsVar === 'pd') pd = target.value;
  3053. \t\t\t\telse if (ax.jsVar === 'ph') ph = target.value;
  3054. \t\t\t\telse if (ax.jsVar === 'pm') pm = target.value;
  3055. \t\t\t\telse if (ax.jsVar === 'option1') option1 = target.value;
  3056. \t\t\t\telse if (ax.jsVar === 'option2') option2 = target.value;
  3057. \t\t\t\tvar lbl = target.closest('.opt-btn');
  3058. \t\t\t\tif (lbl) {
  3059. \t\t\t\t\tvar sib = lbl.parentNode ? lbl.parentNode.querySelectorAll('.opt-btn') : [];
  3060. \t\t\t\t\tfor (var k = 0; k < sib.length; k++) sib[k].classList.remove('is-selected');
  3061. \t\t\t\t\tlbl.classList.add('is-selected');
  3062. \t\t\t\t}
  3063. \t\t\t\tvar grp = (lbl && lbl.closest('.form-group')) || (target.closest('.form-group'));
  3064. \t\t\t\tif (grp) {
  3065. \t\t\t\t\tvar section = grp.querySelector('.rp-section-label');
  3066. \t\t\t\t\tif (section) {
  3067. \t\t\t\t\t\tvar labelHead = section.textContent.split(':')[0].trim();
  3068. \t\t\t\t\t\tsection.innerHTML = labelHead + ': <span>' + target.value + '</span>';
  3069. \t\t\t\t\t}
  3070. \t\t\t\t}
  3071. \t\t\t}
  3072. \t\t})();
  3073. \t\t// 取付/設置工事トグル(off 値が「商品購入のみ」のオプション)は、新規アクセス時に
  3074. \t\t// どちらの radio も未チェックのため初期価格が「商品購入のみ」= 基本工事費抜きになる。
  3075. \t\t// 顧客要望(#10)に合わせ、未選択時は「工事も希望する」(on 側) を初期選択し、
  3076. \t\t// 初期表示を基本工事費込みの最安値に統一する(色・寸法軸の先頭自動選択と同型)。
  3077. \t\t//   ・判定キーは calcGoukei / applyPurchaseOnlyUI と同じ定数「商品購入のみ」。
  3078. \t\t//   ・別用途で op{n} を流用する商品(ウッドデッキ deck_step 等)は radio 値に
  3079. \t\t//     「商品購入のみ」を含まないため対象外(既存挙動を壊さない)。
  3080. \t\t//   ・mitsumori_json 復元やユーザー操作で既に選択済みなら尊重する。
  3081. \t\t(function autoSelectFirstInstall(){
  3082. \t\t\tfor (var i = 0; i <= 10; i++) {
  3083. \t\t\t\tvar nodes = document.querySelectorAll('input[type=\"radio\"][name=\"op' + i + '\"]');
  3084. \t\t\t\tif (nodes.length === 0) continue;
  3085. \t\t\t\t// このグループが「商品購入のみ」を off に持つ工事トグルか判定し、
  3086. \t\t\t\t// 「商品購入のみ」でない側 (= 工事希望 on) を取得する。
  3087. \t\t\t\tvar hasPurchaseOnly = false;
  3088. \t\t\t\tvar onNode = null;
  3089. \t\t\t\tfor (var j = 0; j < nodes.length; j++) {
  3090. \t\t\t\t\tif (nodes[j].value === '商品購入のみ') hasPurchaseOnly = true;
  3091. \t\t\t\t\telse if (!onNode) onNode = nodes[j];
  3092. \t\t\t\t}
  3093. \t\t\t\tif (!hasPurchaseOnly || !onNode) continue;
  3094. \t\t\t\tvar anyChecked = false;
  3095. \t\t\t\tfor (var k = 0; k < nodes.length; k++) {
  3096. \t\t\t\t\tif (nodes[k].checked) { anyChecked = true; break; }
  3097. \t\t\t\t}
  3098. \t\t\t\tif (anyChecked) continue;
  3099. \t\t\t\tonNode.checked = true;
  3100. \t\t\t\t// グローバル op 変数を on 値で埋める(calcGoukei の purchaseOnly 判定が参照)
  3101. \t\t\t\tswitch (i) {
  3102. \t\t\t\t\tcase 0:  op0  = onNode.value; break;
  3103. \t\t\t\t\tcase 1:  op1  = onNode.value; break;
  3104. \t\t\t\t\tcase 2:  op2  = onNode.value; break;
  3105. \t\t\t\t\tcase 3:  op3  = onNode.value; break;
  3106. \t\t\t\t\tcase 4:  op4  = onNode.value; break;
  3107. \t\t\t\t\tcase 5:  op5  = onNode.value; break;
  3108. \t\t\t\t\tcase 6:  op6  = onNode.value; break;
  3109. \t\t\t\t\tcase 7:  op7  = onNode.value; break;
  3110. \t\t\t\t\tcase 8:  op8  = onNode.value; break;
  3111. \t\t\t\t\tcase 9:  op9  = onNode.value; break;
  3112. \t\t\t\t\tcase 10: op10 = onNode.value; break;
  3113. \t\t\t\t}
  3114. \t\t\t\t// opt-btn の is-selected を付け替え
  3115. \t\t\t\tvar lbl = onNode.closest('.opt-btn');
  3116. \t\t\t\tif (lbl) {
  3117. \t\t\t\t\tvar sib = lbl.parentNode ? lbl.parentNode.querySelectorAll('.opt-btn') : [];
  3118. \t\t\t\t\tfor (var s = 0; s < sib.length; s++) sib[s].classList.remove('is-selected');
  3119. \t\t\t\t\tlbl.classList.add('is-selected');
  3120. \t\t\t\t}
  3121. \t\t\t\t// rp-section-label 表示同期 + 現地調査文言(is_removal_unknown / is_tf_kouji)を on 表示に
  3122. \t\t\t\tvar grp = (lbl && lbl.closest('.form-group')) || onNode.closest('.form-group');
  3123. \t\t\t\tif (grp) {
  3124. \t\t\t\t\tvar section = grp.querySelector('.rp-section-label');
  3125. \t\t\t\t\tif (section) {
  3126. \t\t\t\t\t\tvar labelHead = section.textContent.split(':')[0].trim();
  3127. \t\t\t\t\t\tsection.innerHTML = labelHead + ': <span>' + onNode.value + '</span>';
  3128. \t\t\t\t\t}
  3129. \t\t\t\t\tvar note = grp.querySelector('.opt-survey-note[data-op-idx=\"' + i + '\"]');
  3130. \t\t\t\t\tif (note) note.style.display = '';
  3131. \t\t\t\t}
  3132. \t\t\t}
  3133. \t\t})();
  3134. \t\t// ページ読み込み時: 見積金額が「合計」になっているため、カート数量は基本1
  3135. \t\t// sale_type=9(商品のみ購入)だけ通常 EC として数量を引き継ぐ
  3136. \t\t(function initQuantityByType(){
  3137. \t\t\tvar saleType = ";
  3138.         // line 2872
  3139.         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'2872$this->source); })()), "SaleType", [], "any"falsefalsefalse2872), "id", [], "any"falsefalsefalse2872), "html"nulltrue);
  3140.         echo ";
  3141. \t\t\tif (saleType == 9 && \$('#quantity_only').length) {
  3142. \t\t\t\t\$('#quantity').val(parseInt(\$('#quantity_only').val()) || 1);
  3143. \t\t\t} else {
  3144. \t\t\t\t\$('#quantity').val(1);
  3145. \t\t\t\t\$('input[name=\"quantity\"]').val(1);
  3146. \t\t\t}
  3147. \t\t})();
  3148. \t\t// type → ラベルのプレフィックス文字列
  3149. \t\t// option1/option2 のラベルは category 依存 (rd: ランマ/タイプ, sh: サイズプリセット/駆動方式 等).
  3150. \t\t// PHP から渡された option1_label / option2_label を埋め込み、JS 側でラベル更新に使う.
  3151. \t\tvar optLabelMap = {pc:'カラー', pw:'幅', pd:'奥行き', ph:'高さ', pm:'素材',
  3152. \t\t                   option1: '";
  3153.         // line 2885
  3154.         echo twig_escape_filter($this->envtwig_escape_filter($this->env, ((array_key_exists("option1_label"$context)) ? (_twig_default_filter((isset($context["option1_label"]) || array_key_exists("option1_label"$context) ? $context["option1_label"] : (function () { throw new RuntimeError('Variable "option1_label" does not exist.'2885$this->source); })()), "オプション1")) : ("オプション1")), "js"), "html"nulltrue);
  3155.         echo "',
  3156. \t\t                   option2: '";
  3157.         // line 2886
  3158.         echo twig_escape_filter($this->envtwig_escape_filter($this->env, ((array_key_exists("option2_label"$context)) ? (_twig_default_filter((isset($context["option2_label"]) || array_key_exists("option2_label"$context) ? $context["option2_label"] : (function () { throw new RuntimeError('Variable "option2_label" does not exist.'2886$this->source); })()), "オプション2")) : ("オプション2")), "js"), "html"nulltrue);
  3159.         echo "'};
  3160. \t\t// type → input[name]
  3161. \t\tvar optNameMap  = {pc:'color', pw:'pw', pd:'pd', ph:'ph', pm:'pm',
  3162. \t\t                   option1: 'option1', option2: 'option2'};
  3163. \t\t// opt-btn用: 値を直接受け取るラッパー
  3164. \t\tfunction mitsumori_simulation_val(type, value) {
  3165. \t\t\tif (type === 'pc') pc = value;
  3166. \t\t\tif (type === 'pw') pw = value;
  3167. \t\t\tif (type === 'pd') pd = value;
  3168. \t\t\tif (type === 'ph') ph = value;
  3169. \t\t\tif (type === 'pm') pm = value;
  3170. \t\t\tif (type === 'option1') option1 = value;
  3171. \t\t\tif (type === 'option2') option2 = value;
  3172. \t\t\t// is-selected クラスを同グループ内で付け替え
  3173. \t\t\tvar inputName = optNameMap[type];
  3174. \t\t\tif (inputName) {
  3175. \t\t\t\tvar \$btns = \$('input[name=\"' + inputName + '\"]').closest('.opt-btn');
  3176. \t\t\t\t\$btns.removeClass('is-selected');
  3177. \t\t\t\t\$btns.filter(function(){
  3178. \t\t\t\t\treturn \$(this).find('input').val() === value;
  3179. \t\t\t\t}).addClass('is-selected');
  3180. \t\t\t}
  3181. \t\t\t// ラベル行の選択値テキストを更新(例: 「カラー: ブラック」)
  3182. \t\t\tvar labelPrefix = optLabelMap[type];
  3183. \t\t\tif (labelPrefix) {
  3184. \t\t\t\t// 対象のrp-section-labelを特定(input[name]を含む親を遡る)
  3185. \t\t\t\tvar \$group = \$('input[name=\"' + inputName + '\"]').first().closest('.form-group');
  3186. \t\t\t\tvar \$label = \$group.find('.rp-section-label');
  3187. \t\t\t\t\$label.html(labelPrefix + ': <span>' + value + '</span>');
  3188. \t\t\t}
  3189. \t\t\t// simulation本体を呼ぶ(value_idは空でOK、グローバル変数を使う)
  3190. \t\t\tmitsumori_simulation('', '');
  3191. \t\t}
  3192. \t\tmitsumori_simulation(\"\",\"\");
  3193. \t\t// ボタン群: 親幅を超える、または3行以上になる場合は is-scroll を付与し
  3194. \t\t// 縦3段グリッド+横スクロール表示にする(顧客要望「3列くらいで横スクロール」)
  3195. \t\tfunction applyBtnGroupScroll() {
  3196. \t\t\t\$('.rp-btn-group, .opt-btn-group').each(function() {
  3197. \t\t\t\tvar \$group = \$(this);
  3198. \t\t\t\t\$group.removeClass('is-scroll');
  3199. \t\t\t\tvar \$items = \$group.children();
  3200. \t\t\t\tif (\$items.length === 0) return;
  3201. \t\t\t\tvar parentWidth = \$group.parent().width() || \$group.width();
  3202. \t\t\t\tvar totalWidth = 0;
  3203. \t\t\t\tvar gap = parseInt(\$group.css('gap'), 10) || 8;
  3204. \t\t\t\t\$items.each(function() {
  3205. \t\t\t\t\ttotalWidth += this.offsetWidth + gap;
  3206. \t\t\t\t});
  3207. \t\t\t\t// 単一ボタンが親幅を超える、もしくは合計幅が親幅を超える → 横スクロール化
  3208. \t\t\t\tvar anyTooWide = false;
  3209. \t\t\t\t\$items.each(function() {
  3210. \t\t\t\t\tif (this.offsetWidth > parentWidth) { anyTooWide = true; return false; }
  3211. \t\t\t\t});
  3212. \t\t\t\t// 折り返し時の行数も計測
  3213. \t\t\t\tvar tops = {};
  3214. \t\t\t\t\$items.each(function() { tops[this.offsetTop] = true; });
  3215. \t\t\t\tvar rowCount = Object.keys(tops).length;
  3216. \t\t\t\tif (anyTooWide || totalWidth > parentWidth * 2 || rowCount >= 3) {
  3217. \t\t\t\t\t\$group.addClass('is-scroll');
  3218. \t\t\t\t}
  3219. \t\t\t});
  3220. \t\t}
  3221. \t\tapplyBtnGroupScroll();
  3222. \t\t\$(window).on('resize', function() {
  3223. \t\t\tclearTimeout(window._btnScrollTimer);
  3224. \t\t\twindow._btnScrollTimer = setTimeout(applyBtnGroupScroll, 150);
  3225. \t\t});
  3226. \t\t// onload: 見積金額が確定している場合は「工事費込み価格」表示を一致させる
  3227. \t\t(function syncPrice02Display() {
  3228. \t\t\tvar goukeiEl = document.getElementById('mitsumori_goukei');
  3229. \t\t\tvar displayEl = document.getElementById('price02-display');
  3230. \t\t\tif (!goukeiEl || !displayEl) return;
  3231. \t\t\tvar goukeiText = goukeiEl.textContent.trim();
  3232. \t\t\t// ---円(未確定)の場合は書き換えない
  3233. \t\t\tif (goukeiText && goukeiText !== '---円') {
  3234. \t\t\t\tdisplayEl.textContent = goukeiText;
  3235. \t\t\t}
  3236. \t\t\t// 以降の変更にも追従: mitsumori_goukei を監視
  3237. \t\t\tnew MutationObserver(function() {
  3238. \t\t\t\tvar text = goukeiEl.textContent.trim();
  3239. \t\t\t\tif (text && text !== '---円') {
  3240. \t\t\t\t\tdisplayEl.textContent = text;
  3241. \t\t\t\t}
  3242. \t\t\t}).observe(goukeiEl, { childList: true, subtree: true, characterData: true });
  3243. \t\t})();
  3244. \t\tfunction contact_form(product_id){
  3245. \t\t\t\$('#form1').attr('action', '";
  3246.         // line 2983
  3247.         echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getUrl("contact", ["product" => twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'2983$this->source); })()), "id", [], "any"falsefalsefalse2983)]), "html"nulltrue);
  3248.         echo "');
  3249. \t\t\t\$('#form1').submit();
  3250. \t\t}
  3251. \t\t// maisu / madoset は下部の新しい関数定義を使用
  3252. \t\tfunction heibei(bei){
  3253. \t\t\t\$('#heibei').val(parseInt(\$('#heibei').val()) + bei);
  3254. \t\t\tif(parseInt(\$('#heibei').val()) < 1){ \$('#heibei').val(1); }
  3255. \t\t\tif(parseInt(\$('#heibei').val()) > 100){ \$('#heibei').val(100); }
  3256. \t\t\t// goukei に既に枚数を含むため、カート数量は1で固定
  3257. \t\t\t\$('#quantity').val(1);
  3258. \t\t\tmitsumori_simulation('heibei','heibei');
  3259. \t\t}
  3260. \t\tfunction daisu(dai){
  3261. \t\t\t\$('#daisu').val(parseInt(\$('#daisu').val()) + dai);
  3262. \t\t\tif(parseInt(\$('#daisu').val()) < 1){ \$('#daisu').val(1); }
  3263. \t\t\tif(parseInt(\$('#daisu').val()) > 10){ \$('#daisu').val(10); }
  3264. \t\t\t\$('#quantity').val(1);
  3265. \t\t\tmitsumori_simulation('daisu','daisu');
  3266. \t\t}
  3267. \t\t// sale_type=7(数量買い・基本工事費固定)用:個数入力
  3268. \t\tfunction suuryou(n){
  3269. \t\t\t\$('#suuryou').val(parseInt(\$('#suuryou').val()) + n);
  3270. \t\t\tif(parseInt(\$('#suuryou').val()) < 1){ \$('#suuryou').val(1); }
  3271. \t\t\tif(parseInt(\$('#suuryou').val()) > 100){ \$('#suuryou').val(100); }
  3272. \t\t\t\$('#quantity').val(1);
  3273. \t\t\tmitsumori_simulation('suuryou','suuryou');
  3274. \t\t}
  3275. \t\tfunction maisu(mai){
  3276. \t\t\t\$('#maisu').val(parseInt(\$('#maisu').val()) + mai);
  3277. \t\t\t// sale_type=4 (フェンス) は3枚未満不可、6 (芝生) は1枚から
  3278. \t\t\tvar minMai = (SALE_TYPE_ID == 4) ? 3 : 1;
  3279. \t\t\tif(parseInt(\$('#maisu').val()) < minMai){ \$('#maisu').val(minMai); }
  3280. \t\t\tif(parseInt(\$('#maisu').val()) > 100){ \$('#maisu').val(100); }
  3281. \t\t\t\$('#quantity').val(1);
  3282. \t\t\tmitsumori_simulation('maisu','maisu');
  3283. \t\t}
  3284. \t\t// タイプ2: セット数プルダウン連動
  3285. \t\tfunction madosetSelect(val){
  3286. \t\t\tvar v = parseInt(val);
  3287. \t\t\tif(v < 1) v = 1;
  3288. \t\t\tif(v > 20) v = 20;
  3289. \t\t\t\$('#set_count').val(v);
  3290. \t\t\t\$('#quantity').val(1);
  3291. \t\t\t\$('input[name=\"quantity\"]').val(1);
  3292. \t\t\tmitsumori_simulation('set','set_count');
  3293. \t\t}
  3294. \t\t// タイプ2: ±ボタン版(後方互換)
  3295. \t\tfunction madoset(mai){
  3296. \t\t\tvar current = parseInt(\$('#set_count').val()) || 1;
  3297. \t\t\tvar next = current + mai;
  3298. \t\t\tif(next < 1) next = 1;
  3299. \t\t\tif(next > 20) next = 20;
  3300. \t\t\t\$('#set_count').val(next);
  3301. \t\t\tmadosetSelect(next);
  3302. \t\t}
  3303. \t\t// タイプ5: ステップ・フェンス選択値を mitsumori_json に保存するためのグローバル変数
  3304. \t\tvar deck_step = \"";
  3305.         // line 3044
  3306.         if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3044$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "deck_step", [], "any"truetruefalse3044))) {
  3307.             echo twig_escape_filter($this->env, ((twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "deck_step", [], "any"truetruefalse3044)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "deck_step", [], "any"falsefalsefalse3044), "不要")) : ("不要")), "html"nulltrue);
  3308.         } else {
  3309.             echo "不要";
  3310.         }
  3311.         echo "\";
  3312. \t\tvar deck_fence = \"";
  3313.         // line 3045
  3314.         if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3045$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "deck_fence", [], "any"truetruefalse3045))) {
  3315.             echo twig_escape_filter($this->env, ((twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "deck_fence", [], "any"truetruefalse3045)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "deck_fence", [], "any"falsefalsefalse3045), "不要")) : ("不要")), "html"nulltrue);
  3316.         } else {
  3317.             echo "不要";
  3318.         }
  3319.         echo "\";
  3320. \t\t// PDF出力: モーダルの mitsumori_json をフォームに同期してから送信
  3321. \t\tfunction syncPdfJson(){
  3322. \t\t\tvar jsonVal = \$('#mitsumori_json').val();
  3323. \t\t\t\$('#pdf_mitsumori_json').val(jsonVal);
  3324. \t\t}
  3325. \t\t// タイプ9: 商品のみ購入
  3326. \t\tfunction quantityOnly(val){
  3327. \t\t\tvar current = parseInt(\$('#quantity_only').val()) || 1;
  3328. \t\t\tvar next = current + val;
  3329. \t\t\tif(next < 1) next = 1;
  3330. \t\t\t\$('#quantity_only').val(next);
  3331. \t\t\t\$('#quantity').val(next);
  3332. \t\t}
  3333.         // ===== スマホ用下部固定バーへの金額同期 =====
  3334.         // mitsumori_message と mitsumori_goukei を監視して下部バーを更新
  3335.         (function() {
  3336.             var msgTarget   = document.getElementById('mitsumori_message');
  3337.             var goukeiTarget = document.getElementById('mitsumori_goukei');
  3338.             var spPrice     = document.getElementById('sp-mitsumori-price');
  3339.             var spBtn       = document.querySelector('#sp-mitsumori-bar .sp-bar__btn');
  3340.             if (!spPrice || !spBtn) return;
  3341.             function syncBar() {
  3342.                 var msg    = msgTarget ? msgTarget.textContent : '';
  3343.                 var goukei = goukeiTarget ? goukeiTarget.textContent : '---円';
  3344.                 // メッセージが「〇〇を選択してください」の場合はメッセージを表示しボタンを非表示
  3345.                 if (msg.indexOf('選択してください') !== -1) {
  3346.                     spPrice.textContent = msg;
  3347.                     spPrice.style.fontSize = '13px';
  3348.                     spPrice.style.color    = '#888';
  3349.                     spBtn.style.display    = 'none';
  3350.                 } else {
  3351.                     // 価格確定時はボタンを表示
  3352.                     spPrice.textContent = goukei;
  3353.                     spPrice.style.fontSize = '18px';
  3354.                     spPrice.style.color    = '#c00';
  3355.                     spBtn.style.display    = 'block';
  3356.                 }
  3357.             }
  3358.             // 初期値を同期
  3359.             syncBar();
  3360.             // mitsumori_message の変化を監視
  3361.             if (msgTarget) {
  3362.                 new MutationObserver(syncBar).observe(
  3363.                     msgTarget, { childList: true, subtree: true, characterData: true }
  3364.                 );
  3365.             }
  3366.             // mitsumori_goukei の変化も監視
  3367.             if (goukeiTarget) {
  3368.                 new MutationObserver(syncBar).observe(
  3369.                     goukeiTarget, { childList: true, subtree: true, characterData: true }
  3370.                 );
  3371.             }
  3372.         })();
  3373.         // ===== スマホ用 お見積りの詳細 ボトムシート 開閉 =====
  3374.         // 現在の内訳カード(.mitsumori-card-pc .card-body)を複製して表示する。
  3375.         // 価格計算ロジックには触れず、その時点で表示中の内訳をそのまま見せる。
  3376.         // window に直接ぶら下げてスコープに依存せず onclick から呼べるようにする。
  3377.         window.openSpMitsumoriDetail = function () {
  3378.             var sheet = document.getElementById('sp-mitsumori-detail');
  3379.             var body  = document.getElementById('sp-detail-body');
  3380.             var src   = document.querySelector('.mitsumori-card-pc .card-body');
  3381.             if (!sheet || !body) return;
  3382.             body.innerHTML = '';
  3383.             if (src) {
  3384.                 // 複製し、重複 id を避けるため clone 側の id を除去する
  3385.                 var clone = src.cloneNode(true);
  3386.                 var ided = clone.querySelectorAll('[id]');
  3387.                 for (var i = 0; i < ided.length; i++) { ided[i].removeAttribute('id'); }
  3388.                 body.appendChild(clone);
  3389.             }
  3390.             sheet.classList.add('is-open');
  3391.             sheet.setAttribute('aria-hidden', 'false');
  3392.             document.body.style.overflow = 'hidden';
  3393.         };
  3394.         window.closeSpMitsumoriDetail = function () {
  3395.             var sheet = document.getElementById('sp-mitsumori-detail');
  3396.             if (!sheet) return;
  3397.             sheet.classList.remove('is-open');
  3398.             sheet.setAttribute('aria-hidden', 'true');
  3399.             document.body.style.overflow = '';
  3400.         };
  3401.         // ===== 現在のお見積り額: 折りたたみトグルボタンのテキスト切り替え =====
  3402.         (function() {
  3403.             var card = document.querySelector('.mitsumori-card-pc');
  3404.             var btn  = document.querySelector('.btn-mitsumori-toggle .toggle-icon');
  3405.             if (!card || !btn) return;
  3406.             // MutationObserverでcollapsed-cardクラスの変化を監視
  3407.             new MutationObserver(function() {
  3408.                 if (card.classList.contains('collapsed-card')) {
  3409.                     btn.textContent = '▼ 詳細';
  3410.                 } else {
  3411.                     btn.textContent = '▲ 閉じる';
  3412.                 }
  3413.             }).observe(card, { attributes: true, attributeFilter: ['class'] });
  3414.         })();
  3415.         // ===== エリア案内: スマホのみタップで展開 =====
  3416.         (function() {
  3417.             var notice = document.querySelector('.ec-areaNotice');
  3418.             if (!notice) return;
  3419.             notice.addEventListener('click', function(e) {
  3420.                 if (window.innerWidth > 767) return;
  3421.                 // リンククリック時は展開/折りたたみせずリンク遷移
  3422.                 if (e.target.tagName === 'A') return;
  3423.                 notice.classList.toggle('is-open');
  3424.             });
  3425.         })();
  3426.     </script>
  3427.     <script type=\"application/ld+json\">
  3428.     {
  3429.         \"@context\": \"https://schema.org/\",
  3430.         \"@type\": \"Product\",
  3431.         \"name\": \"";
  3432.         // line 3168
  3433.         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3168$this->source); })()), "name", [], "any"falsefalsefalse3168), "html"nulltrue);
  3434.         echo "\",
  3435.         \"image\": [
  3436.             ";
  3437.         // line 3170
  3438.         $context['_parent'] = $context;
  3439.         $context['_seq'] = twig_ensure_traversable(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3170$this->source); })()), "ProductImage", [], "any"falsefalsefalse3170));
  3440.         $context['_iterated'] = false;
  3441.         $context['loop'] = [
  3442.           'parent' => $context['_parent'],
  3443.           'index0' => 0,
  3444.           'index'  => 1,
  3445.           'first'  => true,
  3446.         ];
  3447.         if (is_array($context['_seq']) || (is_object($context['_seq']) && $context['_seq'] instanceof \Countable)) {
  3448.             $length count($context['_seq']);
  3449.             $context['loop']['revindex0'] = $length 1;
  3450.             $context['loop']['revindex'] = $length;
  3451.             $context['loop']['length'] = $length;
  3452.             $context['loop']['last'] = === $length;
  3453.         }
  3454.         foreach ($context['_seq'] as $context["_key"] => $context["img"]) {
  3455.             // line 3171
  3456.             echo "                \"";
  3457.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["app"]) || array_key_exists("app"$context) ? $context["app"] : (function () { throw new RuntimeError('Variable "app" does not exist.'3171$this->source); })()), "request", [], "any"falsefalsefalse3171), "schemeAndHttpHost", [], "any"falsefalsefalse3171), "html"nulltrue);
  3458.             echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl($context["img"], "save_image"), "html"nulltrue);
  3459.             echo "\"";
  3460.             if ( !twig_get_attribute($this->env$this->source$context["loop"], "last", [], "any"falsefalsefalse3171)) {
  3461.                 echo ",";
  3462.             }
  3463.             // line 3172
  3464.             echo "
  3465.             ";
  3466.             $context['_iterated'] = true;
  3467.             ++$context['loop']['index0'];
  3468.             ++$context['loop']['index'];
  3469.             $context['loop']['first'] = false;
  3470.             if (isset($context['loop']['length'])) {
  3471.                 --$context['loop']['revindex0'];
  3472.                 --$context['loop']['revindex'];
  3473.                 $context['loop']['last'] = === $context['loop']['revindex0'];
  3474.             }
  3475.         }
  3476.         if (!$context['_iterated']) {
  3477.             // line 3174
  3478.             echo "                \"";
  3479.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["app"]) || array_key_exists("app"$context) ? $context["app"] : (function () { throw new RuntimeError('Variable "app" does not exist.'3174$this->source); })()), "request", [], "any"falsefalsefalse3174), "schemeAndHttpHost", [], "any"falsefalsefalse3174), "html"nulltrue);
  3480.             echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl($this->extensions['Eccube\Twig\Extension\EccubeExtension']->getNoImageProduct(""), "save_image"), "html"nulltrue);
  3481.             echo "\"
  3482.             ";
  3483.         }
  3484.         $_parent $context['_parent'];
  3485.         unset($context['_seq'], $context['_iterated'], $context['_key'], $context['img'], $context['_parent'], $context['loop']);
  3486.         $context array_intersect_key($context$_parent) + $_parent;
  3487.         // line 3176
  3488.         echo "        ],
  3489.         \"description\": \"";
  3490.         // line 3177
  3491.         echo twig_escape_filter($this->envtwig_slice($this->envtwig_replace_filter(((twig_get_attribute($this->env$this->source, ($context["Product"] ?? null), "description_list", [], "any"truetruefalse3177)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["Product"] ?? null), "description_list", [], "any"falsefalsefalse3177), twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3177$this->source); })()), "description_detail", [], "any"falsefalsefalse3177))) : (twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3177$this->source); })()), "description_detail", [], "any"falsefalsefalse3177))), ["
  3492. => """ " => ""]), 0300), "html"nulltrue);
  3493.         echo "\",
  3494.         ";
  3495.         // line 3178
  3496.         if (twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3178$this->source); })()), "code_min", [], "any"falsefalsefalse3178)) {
  3497.             // line 3179
  3498.             echo "        \"sku\": \"";
  3499.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3179$this->source); })()), "code_min", [], "any"falsefalsefalse3179), "html"nulltrue);
  3500.             echo "\",
  3501.         ";
  3502.         }
  3503.         // line 3181
  3504.         echo "        \"offers\": {
  3505.             \"@type\": \"Offer\",
  3506.             \"url\": \"";
  3507.         // line 3183
  3508.         echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getUrl("product_detail", ["id" => twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3183$this->source); })()), "id", [], "any"falsefalsefalse3183)]), "html"nulltrue);
  3509.         echo "\",
  3510.             \"priceCurrency\": \"";
  3511.         // line 3184
  3512.         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["eccube_config"]) || array_key_exists("eccube_config"$context) ? $context["eccube_config"] : (function () { throw new RuntimeError('Variable "eccube_config" does not exist.'3184$this->source); })()), "currency", [], "any"falsefalsefalse3184), "html"nulltrue);
  3513.         echo "\",
  3514.             \"price\": ";
  3515.         // line 3185
  3516.         ((twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3185$this->source); })()), "getPrice02IncTaxMin", [], "any"falsefalsefalse3185)) ? (print (twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3185$this->source); })()), "getPrice02IncTaxMin", [], "any"falsefalsefalse3185), "html"nulltrue))) : (print (0)));
  3517.         echo ",
  3518.             \"availability\": \"";
  3519.         // line 3186
  3520.         echo ((twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3186$this->source); })()), "stock_find", [], "any"falsefalsefalse3186)) ? ("InStock") : ("OutOfStock"));
  3521.         echo "\"
  3522.         }
  3523.     }
  3524.     </script>
  3525. ";
  3526.         
  3527.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->leave($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof);
  3528.         
  3529.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->leave($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof);
  3530.     }
  3531.     // line 3193
  3532.     public function block_main($context, array $blocks = [])
  3533.     {
  3534.         $macros $this->macros;
  3535.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  3536.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->enter($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""main"));
  3537.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02 $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  3538.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->enter($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""main"));
  3539.         // line 3194
  3540.         echo "    ";
  3541.         // line 3195
  3542.         echo "    ";
  3543.         $context["option1_label"] = "オプション1";
  3544.         // line 3196
  3545.         echo "    ";
  3546.         $context["option2_label"] = "オプション2";
  3547.         // line 3197
  3548.         echo "    ";
  3549.         // line 3200
  3550.         echo "    ";
  3551.         $context["is_cat43"] = false;
  3552.         // line 3201
  3553.         echo "    ";
  3554.         if ( !twig_test_empty(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3201$this->source); })()), "ProductCategories", [], "any"falsefalsefalse3201))) {
  3555.             // line 3202
  3556.             echo "        ";
  3557.             $context['_parent'] = $context;
  3558.             $context['_seq'] = twig_ensure_traversable(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3202$this->source); })()), "ProductCategories", [], "any"falsefalsefalse3202));
  3559.             foreach ($context['_seq'] as $context["_key"] => $context["pcat"]) {
  3560.                 // line 3203
  3561.                 echo "            ";
  3562.                 if ((twig_get_attribute($this->env$this->source$context["pcat"], "category_id", [], "any"falsefalsefalse3203) == 31)) {
  3563.                     $context["option1_label"] = "サイズプリセット";
  3564.                     $context["option2_label"] = "駆動方式";
  3565.                 }
  3566.                 // line 3204
  3567.                 echo "            ";
  3568.                 if ((twig_get_attribute($this->env$this->source$context["pcat"], "category_id", [], "any"falsefalsefalse3204) == 43)) {
  3569.                     $context["option1_label"] = "ランマ";
  3570.                     $context["option2_label"] = "タイプ";
  3571.                     $context["is_cat43"] = true;
  3572.                 }
  3573.                 // line 3205
  3574.                 echo "            ";
  3575.                 if ((twig_get_attribute($this->env$this->source$context["pcat"], "category_id", [], "any"falsefalsefalse3205) == 15)) {
  3576.                     $context["option1_label"] = "棚タイプ";
  3577.                 }
  3578.                 // line 3206
  3579.                 echo "            ";
  3580.                 if ((twig_get_attribute($this->env$this->source$context["pcat"], "category_id", [], "any"falsefalsefalse3206) == 17)) {
  3581.                     $context["option1_label"] = "窓タイプ";
  3582.                 }
  3583.                 // line 3207
  3584.                 echo "        ";
  3585.             }
  3586.             $_parent $context['_parent'];
  3587.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pcat'], $context['_parent'], $context['loop']);
  3588.             $context array_intersect_key($context$_parent) + $_parent;
  3589.             // line 3208
  3590.             echo "    ";
  3591.         }
  3592.         // line 3209
  3593.         echo "    <div class=\"ec-productRole\" style=\"margin-top:20px;\">
  3594.         <div class=\"ec-grid2\">
  3595.             <div class=\"ec-grid2__cell\">
  3596.                 <div class=\"ec-sliderItemRole\">
  3597. \t                ";
  3598.         // line 3214
  3599.         echo "\t                <div class=\"ec-productRole__title\">
  3600. \t                    <div class=\"ec-productRole__titleRow\">
  3601. \t                        <h2 class=\"ec-headingTitle\">";
  3602.         // line 3216
  3603.         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3216$this->source); })()), "name", [], "any"falsefalsefalse3216), "html"nulltrue);
  3604.         echo "</h2>
  3605. \t                        <div class=\"ec-share-inline\">
  3606. \t                            <a href=\"https://twitter.com/share?url=";
  3607.         // line 3218
  3608.         echo twig_escape_filter($this->envtwig_urlencode_filter(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["app"]) || array_key_exists("app"$context) ? $context["app"] : (function () { throw new RuntimeError('Variable "app" does not exist.'3218$this->source); })()), "request", [], "any"falsefalsefalse3218), "uri", [], "any"falsefalsefalse3218)), "html"nulltrue);
  3609.         echo "&text=";
  3610.         echo twig_escape_filter($this->envtwig_urlencode_filter(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3218$this->source); })()), "name", [], "any"falsefalsefalse3218)), "html"nulltrue);
  3611.         echo "\"
  3612. \t                               class=\"share-twitter\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"Xでシェア\">
  3613. \t                                <svg viewBox=\"0 0 24 24\" style=\"width:15px;height:15px;fill:#fff;\"><path d=\"M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-4.714-6.231-5.401 6.231H2.74l7.73-8.835L1.254 2.25H8.08l4.254 5.622L18.244 2.25zm-1.161 17.52h1.833L7.084 4.126H5.117z\"/></svg>
  3614. \t                            </a>
  3615. \t                            <a href=\"https://www.instagram.com/\" class=\"share-facebook\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"Instagram\">
  3616. \t                                <svg viewBox=\"0 0 24 24\" style=\"width:15px;height:15px;fill:#fff;\"><path d=\"M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zM12 0C8.741 0 8.333.014 7.053.072 2.695.272.273 2.69.073 7.052.014 8.333 0 8.741 0 12c0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98C8.333 23.986 8.741 24 12 24c3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98C15.668.014 15.259 0 12 0zm0 5.838a6.162 6.162 0 100 12.324 6.162 6.162 0 000-12.324zM12 16a4 4 0 110-8 4 4 0 010 8zm6.406-11.845a1.44 1.44 0 100 2.881 1.44 1.44 0 000-2.881z\"/></svg>
  3617. \t                            </a>
  3618. \t                            <a href=\"https://social-plugins.line.me/lineit/share?url=";
  3619.         // line 3225
  3620.         echo twig_escape_filter($this->envtwig_urlencode_filter(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["app"]) || array_key_exists("app"$context) ? $context["app"] : (function () { throw new RuntimeError('Variable "app" does not exist.'3225$this->source); })()), "request", [], "any"falsefalsefalse3225), "uri", [], "any"falsefalsefalse3225)), "html"nulltrue);
  3621.         echo "\"
  3622. \t                               class=\"share-line\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"LINEでシェア\">
  3623. \t                                <i class=\"fab fa-line\"></i>
  3624. \t                            </a>
  3625. \t                        </div>
  3626. \t                    </div>
  3627. \t                </div>
  3628.                     ";
  3629.         // line 3232
  3630.         if (twig_get_attribute($this->env$this->source, (isset($context["BaseInfo"]) || array_key_exists("BaseInfo"$context) ? $context["BaseInfo"] : (function () { throw new RuntimeError('Variable "BaseInfo" does not exist.'3232$this->source); })()), "option_favorite_product", [], "any"falsefalsefalse3232)) {
  3631.             // line 3233
  3632.             echo "                     <div style=\"position:relative;top: 20px;left: 10px;z-index:100;\">
  3633. \t\t\t\t\t\t";
  3634.             // line 3234
  3635.             if (((isset($context["is_favorite"]) || array_key_exists("is_favorite"$context) ? $context["is_favorite"] : (function () { throw new RuntimeError('Variable "is_favorite" does not exist.'3234$this->source); })()) == false)) {
  3636.                 // line 3235
  3637.                 echo "                        <form action=\"";
  3638.                 echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getUrl("product_add_favorite", ["id" => twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3235$this->source); })()), "id", [], "any"falsefalsefalse3235)]), "html"nulltrue);
  3639.                 echo "\" method=\"post\">
  3640.                            <button type=\"submit\" id=\"favorite\" class=\"favorite\">&#9825;</button>
  3641.                         </form>
  3642.                         ";
  3643.             } else {
  3644.                 // line 3239
  3645.                 echo "                        <form action=\"";
  3646.                 echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getUrl("product_add_favorite", ["id" => twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3239$this->source); })()), "id", [], "any"falsefalsefalse3239)]), "html"nulltrue);
  3647.                 echo "\" method=\"post\">
  3648.                            <button type=\"submit\" id=\"favorite\" class=\"favorite\" style=\"color:red;\">&#9829;</button>
  3649.                         </form>
  3650.                         ";
  3651.             }
  3652.             // line 3243
  3653.             echo "                     </div>
  3654.                     ";
  3655.         }
  3656.         // line 3245
  3657.         echo "                    <div class=\"item_visual\">
  3658.                         ";
  3659.         // line 3246
  3660.         $context['_parent'] = $context;
  3661.         $context['_seq'] = twig_ensure_traversable(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3246$this->source); })()), "ProductImage", [], "any"falsefalsefalse3246));
  3662.         $context['_iterated'] = false;
  3663.         $context['loop'] = [
  3664.           'parent' => $context['_parent'],
  3665.           'index0' => 0,
  3666.           'index'  => 1,
  3667.           'first'  => true,
  3668.         ];
  3669.         if (is_array($context['_seq']) || (is_object($context['_seq']) && $context['_seq'] instanceof \Countable)) {
  3670.             $length count($context['_seq']);
  3671.             $context['loop']['revindex0'] = $length 1;
  3672.             $context['loop']['revindex'] = $length;
  3673.             $context['loop']['length'] = $length;
  3674.             $context['loop']['last'] = === $length;
  3675.         }
  3676.         foreach ($context['_seq'] as $context["_key"] => $context["ProductImage"]) {
  3677.             // line 3247
  3678.             echo "                            <div class=\"slide-item\">
  3679.                                 <a class=\"js-zoom\" href=\"";
  3680.             // line 3248
  3681.             echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl($context["ProductImage"], "save_image"), "html"nulltrue);
  3682.             echo "\" aria-label=\"";
  3683.             ((twig_get_attribute($this->env$this->source$context["loop"], "first", [], "any"falsefalsefalse3248)) ? (print (twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3248$this->source); })()), "name", [], "any"falsefalsefalse3248), "html"nulltrue))) : (print ("")));
  3684.             echo "\">
  3685.                                     <img src=\"";
  3686.             // line 3249
  3687.             echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl($context["ProductImage"], "save_image"), "html"nulltrue);
  3688.             echo "\" alt=\"";
  3689.             ((twig_get_attribute($this->env$this->source$context["loop"], "first", [], "any"falsefalsefalse3249)) ? (print (twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3249$this->source); })()), "name", [], "any"falsefalsefalse3249), "html"nulltrue))) : (print ("")));
  3690.             echo "\" width=\"550\" height=\"550\" style=\"max-height: 400px;\"";
  3691.             if ((twig_get_attribute($this->env$this->source$context["loop"], "index", [], "any"falsefalsefalse3249) > 1)) {
  3692.                 echo " loading=\"lazy\"";
  3693.             }
  3694.             echo ">
  3695.                                 </a>
  3696.                             </div>
  3697.                         ";
  3698.             $context['_iterated'] = true;
  3699.             ++$context['loop']['index0'];
  3700.             ++$context['loop']['index'];
  3701.             $context['loop']['first'] = false;
  3702.             if (isset($context['loop']['length'])) {
  3703.                 --$context['loop']['revindex0'];
  3704.                 --$context['loop']['revindex'];
  3705.                 $context['loop']['last'] = === $context['loop']['revindex0'];
  3706.             }
  3707.         }
  3708.         if (!$context['_iterated']) {
  3709.             // line 3253
  3710.             echo "                            <div class=\"slide-item\"><img src=\"";
  3711.             echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl($this->extensions['Eccube\Twig\Extension\EccubeExtension']->getNoImageProduct(""), "save_image"), "html"nulltrue);
  3712.             echo "\" alt=\"";
  3713.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3253$this->source); })()), "name", [], "any"falsefalsefalse3253), "html"nulltrue);
  3714.             echo "\" width=\"550\" height=\"550\" style=\"max-height: 400px;\"></div>
  3715.                         ";
  3716.         }
  3717.         $_parent $context['_parent'];
  3718.         unset($context['_seq'], $context['_iterated'], $context['_key'], $context['ProductImage'], $context['_parent'], $context['loop']);
  3719.         $context array_intersect_key($context$_parent) + $_parent;
  3720.         // line 3255
  3721.         echo "                    </div>
  3722.                     <div class=\"item_nav\">
  3723.                         ";
  3724.         // line 3257
  3725.         $context['_parent'] = $context;
  3726.         $context['_seq'] = twig_ensure_traversable(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3257$this->source); })()), "ProductImage", [], "any"falsefalsefalse3257));
  3727.         $context['loop'] = [
  3728.           'parent' => $context['_parent'],
  3729.           'index0' => 0,
  3730.           'index'  => 1,
  3731.           'first'  => true,
  3732.         ];
  3733.         if (is_array($context['_seq']) || (is_object($context['_seq']) && $context['_seq'] instanceof \Countable)) {
  3734.             $length count($context['_seq']);
  3735.             $context['loop']['revindex0'] = $length 1;
  3736.             $context['loop']['revindex'] = $length;
  3737.             $context['loop']['length'] = $length;
  3738.             $context['loop']['last'] = === $length;
  3739.         }
  3740.         foreach ($context['_seq'] as $context["_key"] => $context["ProductImage"]) {
  3741.             // line 3258
  3742.             echo "                            <div class=\"slideThumb\" data-index=\"";
  3743.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["loop"], "index0", [], "any"falsefalsefalse3258), "html"nulltrue);
  3744.             echo "\"><img src=\"";
  3745.             echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl($context["ProductImage"], "save_image"), "html"nulltrue);
  3746.             echo "\" alt=\"\" width=\"80\" height=\"80\" loading=\"lazy\"></div>
  3747.                         ";
  3748.             ++$context['loop']['index0'];
  3749.             ++$context['loop']['index'];
  3750.             $context['loop']['first'] = false;
  3751.             if (isset($context['loop']['length'])) {
  3752.                 --$context['loop']['revindex0'];
  3753.                 --$context['loop']['revindex'];
  3754.                 $context['loop']['last'] = === $context['loop']['revindex0'];
  3755.             }
  3756.         }
  3757.         $_parent $context['_parent'];
  3758.         unset($context['_seq'], $context['_iterated'], $context['_key'], $context['ProductImage'], $context['_parent'], $context['loop']);
  3759.         $context array_intersect_key($context$_parent) + $_parent;
  3760.         // line 3260
  3761.         echo "                    </div>
  3762.                 </div>
  3763.                     ";
  3764.         // line 3265
  3765.         echo "                    <div class=\"ec-areaNotice\" style=\"margin-top:16px;margin-right:10px;\">
  3766.                         <div class=\"ec-areaNotice__inner\">
  3767.                             <div class=\"ec-areaNotice__icon\">📍</div>
  3768.                             <div class=\"ec-areaNotice__body\">
  3769.                                 <p class=\"ec-areaNotice__title\">施工対応エリアについて</p>
  3770.                                 <div class=\"ec-areaNotice__detail\">
  3771.                                     <p class=\"ec-areaNotice__text\">
  3772.                                         当店の施工サービスは、<strong>山梨県全域</strong>および<br>
  3773.                                         <strong>諏訪エリア(諏訪市・岡谷市・茅野市・諏訪郡)</strong>を対象としております。<br>
  3774.                                         上記エリア外のお客様には、商品のみのご購入が可能でございます。<br>
  3775.                                         ご不明な点がございましたら、お気軽にお問い合わせください。
  3776.                                     </p>
  3777.                                     <a class=\"ec-areaNotice__link\" href=\"";
  3778.         // line 3277
  3779.         echo $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getUrl("contact");
  3780.         echo "\">エリア外のお客様・ご相談はこちら →</a>
  3781.                                 </div>
  3782.                             </div>
  3783.                         </div>
  3784.                     </div>
  3785.             </div>
  3786.             <div class=\"ec-grid2__cell2\">
  3787.                 <div class=\"ec-productRole__profile\" >
  3788.                     ";
  3789.         // line 3288
  3790.         echo "                    ";
  3791.         $context["hidden_cat_ids"] = [=> 21=> 28=> 44];
  3792.         // line 3289
  3793.         echo "                    ";
  3794.         if ( !twig_test_empty(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3289$this->source); })()), "ProductCategories", [], "any"falsefalsefalse3289))) {
  3795.             // line 3290
  3796.             echo "                        <div class=\"ec-productRole__category\" style=\"padding:10px 0;\">
  3797.                             ";
  3798.             // line 3291
  3799.             $context['_parent'] = $context;
  3800.             $context['_seq'] = twig_ensure_traversable(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3291$this->source); })()), "ProductCategories", [], "any"falsefalsefalse3291));
  3801.             foreach ($context['_seq'] as $context["_key"] => $context["ProductCategory"]) {
  3802.                 // line 3292
  3803.                 echo "                                ";
  3804.                 if (!twig_in_filter(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source$context["ProductCategory"], "Category", [], "any"falsefalsefalse3292), "id", [], "any"falsefalsefalse3292), (isset($context["hidden_cat_ids"]) || array_key_exists("hidden_cat_ids"$context) ? $context["hidden_cat_ids"] : (function () { throw new RuntimeError('Variable "hidden_cat_ids" does not exist.'3292$this->source); })()))) {
  3805.                     // line 3293
  3806.                     echo "                                <ul>
  3807.                                     <li>
  3808.                                         ";
  3809.                     // line 3295
  3810.                     $context['_parent'] = $context;
  3811.                     $context['_seq'] = twig_ensure_traversable(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source$context["ProductCategory"], "Category", [], "any"falsefalsefalse3295), "path", [], "any"falsefalsefalse3295));
  3812.                     $context['loop'] = [
  3813.                       'parent' => $context['_parent'],
  3814.                       'index0' => 0,
  3815.                       'index'  => 1,
  3816.                       'first'  => true,
  3817.                     ];
  3818.                     if (is_array($context['_seq']) || (is_object($context['_seq']) && $context['_seq'] instanceof \Countable)) {
  3819.                         $length count($context['_seq']);
  3820.                         $context['loop']['revindex0'] = $length 1;
  3821.                         $context['loop']['revindex'] = $length;
  3822.                         $context['loop']['length'] = $length;
  3823.                         $context['loop']['last'] = === $length;
  3824.                     }
  3825.                     foreach ($context['_seq'] as $context["_key"] => $context["Category"]) {
  3826.                         // line 3296
  3827.                         echo "                                            <a href=\"";
  3828.                         echo $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getUrl("product_list");
  3829.                         echo "?category_id=";
  3830.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["Category"], "id", [], "any"falsefalsefalse3296), "html"nulltrue);
  3831.                         echo "\">";
  3832.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["Category"], "name", [], "any"falsefalsefalse3296), "html"nulltrue);
  3833.                         echo "</a>";
  3834.                         if ((twig_get_attribute($this->env$this->source$context["loop"], "last", [], "any"falsefalsefalse3296) == false)) {
  3835.                             // line 3297
  3836.                             echo "                                            <span>></span>";
  3837.                         }
  3838.                         ++$context['loop']['index0'];
  3839.                         ++$context['loop']['index'];
  3840.                         $context['loop']['first'] = false;
  3841.                         if (isset($context['loop']['length'])) {
  3842.                             --$context['loop']['revindex0'];
  3843.                             --$context['loop']['revindex'];
  3844.                             $context['loop']['last'] = === $context['loop']['revindex0'];
  3845.                         }
  3846.                     }
  3847.                     $_parent $context['_parent'];
  3848.                     unset($context['_seq'], $context['_iterated'], $context['_key'], $context['Category'], $context['_parent'], $context['loop']);
  3849.                     $context array_intersect_key($context$_parent) + $_parent;
  3850.                     // line 3299
  3851.                     echo "                                    </li>
  3852.                                 </ul>
  3853.                                 ";
  3854.                 }
  3855.                 // line 3302
  3856.                 echo "                            ";
  3857.             }
  3858.             $_parent $context['_parent'];
  3859.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['ProductCategory'], $context['_parent'], $context['loop']);
  3860.             $context array_intersect_key($context$_parent) + $_parent;
  3861.             // line 3303
  3862.             echo "                        </div>
  3863.                     ";
  3864.         }
  3865.         // line 3305
  3866.         echo "                    ";
  3867.         // line 3306
  3868.         echo "                    <div class=\"ec-productRole__price\">
  3869. \t\t\t\t\t\t<span style=\"color:black;font-size:15px;\">工事費込み価格</span>
  3870.                         ";
  3871.         // line 3308
  3872.         if (twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3308$this->source); })()), "hasProductClass", [], "any"falsefalsefalse3308)) {
  3873.             // line 3309
  3874.             if ((twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3309$this->source); })()), "getPrice02IncTaxMin", [], "any"falsefalsefalse3309) == twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3309$this->source); })()), "getPrice02IncTaxMax", [], "any"falsefalsefalse3309))) {
  3875.                 // line 3310
  3876.                 echo "                                <div class=\"ec-price\">
  3877.                                     <span id=\"price02-display\" class=\"ec-price__price price02-default\">";
  3878.                 // line 3311
  3879.                 echo twig_escape_filter($this->env$this->extensions['Eccube\Twig\Extension\EccubeExtension']->getPriceFilter(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3311$this->source); })()), "getPrice02IncTaxMin", [], "any"falsefalsefalse3311)), "html"nulltrue);
  3880.                 echo "</span>
  3881.                                     <span class=\"ec-price__tax\">(";
  3882.                 // line 3312
  3883.                 echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\TranslationExtension']->trans("税込"), "html"nulltrue);
  3884.                 echo ")~</span>
  3885.                                 </div>
  3886.                             ";
  3887.             } else {
  3888.                 // line 3315
  3889.                 echo "                                <div class=\"ec-price\">
  3890.                                     <span id=\"price02-display\" class=\"ec-price__price price02-default\">";
  3891.                 // line 3316
  3892.                 echo twig_escape_filter($this->env$this->extensions['Eccube\Twig\Extension\EccubeExtension']->getPriceFilter(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3316$this->source); })()), "getPrice02IncTaxMin", [], "any"falsefalsefalse3316)), "html"nulltrue);
  3893.                 echo " ~ ";
  3894.                 echo twig_escape_filter($this->env$this->extensions['Eccube\Twig\Extension\EccubeExtension']->getPriceFilter(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3316$this->source); })()), "getPrice02IncTaxMax", [], "any"falsefalsefalse3316)), "html"nulltrue);
  3895.                 echo "</span>
  3896.                                     <span class=\"ec-price__tax\">(";
  3897.                 // line 3317
  3898.                 echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\TranslationExtension']->trans("税込"), "html"nulltrue);
  3899.                 echo ")</span>
  3900.                                 </div>
  3901.                             ";
  3902.             }
  3903.             // line 3320
  3904.             echo "                        ";
  3905.         } else {
  3906.             // line 3321
  3907.             echo "                            <div class=\"ec-price\">
  3908.                                 <span id=\"price02-display\" class=\"ec-price__price\">";
  3909.             // line 3322
  3910.             echo twig_escape_filter($this->env$this->extensions['Eccube\Twig\Extension\EccubeExtension']->getPriceFilter(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3322$this->source); })()), "getPrice02IncTaxMin", [], "any"falsefalsefalse3322)), "html"nulltrue);
  3911.             echo "</span>
  3912.                                     <span class=\"ec-price__tax\">(";
  3913.             // line 3323
  3914.             echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\TranslationExtension']->trans("税込"), "html"nulltrue);
  3915.             echo ")~</span>
  3916.                             </div>
  3917.                         ";
  3918.         }
  3919.         // line 3326
  3920.         echo "                    </div>
  3921.                     ";
  3922.         // line 3328
  3923.         echo "                    <ul class=\"ec-productRole__tags\">
  3924.                         ";
  3925.         // line 3329
  3926.         $context['_parent'] = $context;
  3927.         $context['_seq'] = twig_ensure_traversable(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3329$this->source); })()), "Tags", [], "any"falsefalsefalse3329));
  3928.         foreach ($context['_seq'] as $context["_key"] => $context["Tag"]) {
  3929.             // line 3330
  3930.             echo "                            <li class=\"ec-productRole__tag tag_";
  3931.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["Tag"], "id", [], "any"falsefalsefalse3330), "html"nulltrue);
  3932.             echo "\">";
  3933.             echo twig_escape_filter($this->env$context["Tag"], "html"nulltrue);
  3934.             echo "</li>
  3935.                         ";
  3936.         }
  3937.         $_parent $context['_parent'];
  3938.         unset($context['_seq'], $context['_iterated'], $context['_key'], $context['Tag'], $context['_parent'], $context['loop']);
  3939.         $context array_intersect_key($context$_parent) + $_parent;
  3940.         // line 3332
  3941.         echo "                    </ul>
  3942.                     ";
  3943.         // line 3334
  3944.         echo "                    ";
  3945.         if ( !twig_test_empty(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3334$this->source); })()), "code_min", [], "any"falsefalsefalse3334))) {
  3946.             // line 3335
  3947.             echo "                        <div class=\"ec-productRole__code\">
  3948.                             ";
  3949.             // line 3336
  3950.             echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\TranslationExtension']->trans("商品コード"), "html"nulltrue);
  3951.             echo ": <span class=\"product-code-default\">";
  3952.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3336$this->source); })()), "code_min", [], "any"falsefalsefalse3336), "html"nulltrue);
  3953.             if ((twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3336$this->source); })()), "code_min", [], "any"falsefalsefalse3336) != twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3336$this->source); })()), "code_max", [], "any"falsefalsefalse3336))) {
  3954.                 echo " ~ ";
  3955.                 echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3336$this->source); })()), "code_max", [], "any"falsefalsefalse3336), "html"nulltrue);
  3956.             }
  3957.             echo "</span>
  3958.                         </div>
  3959.                     ";
  3960.         }
  3961.         // line 3339
  3962.         echo "
  3963.                     <div class=\"ec-productRole__description\">
  3964. \t\t\t\t        <div class=\"ec-rectHeading\">
  3965. \t\t\t\t            <h4>製品情報</h4>
  3966. \t\t\t\t        </div>
  3967. \t\t\t\t\t\t";
  3968.         // line 3344
  3969.         echo twig_nl2br(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3344$this->source); })()), "sales_infomation", [], "any"falsefalsefalse3344));
  3970.         echo "
  3971.                     </div>
  3972. \t\t\t\t\t<div class=\"card card-danger\" style=\"clear:both;margin:1px;\">
  3973. \t\t\t\t\t  <div class=\"card-header\">
  3974. \t\t\t\t\t    <h3 class=\"card-title\">見積シミュレーション</h3>
  3975. \t\t\t\t\t  </div>
  3976. \t\t\t\t\t  <div class=\"card-body p-2\">
  3977.                         ";
  3978.         // line 3353
  3979.         $context["related_image"] = $this->extensions['Plugin\ProductField\Twig\Extension\EccubeExtension']->getProduct_field(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3353$this->source); })()), "id", [], "any"falsefalsefalse3353), "related_image");
  3980.         // line 3354
  3981.         echo "                        ";
  3982.         // line 3355
  3983.         echo "                        ";
  3984.         $context["img1"] = ((isset($context["related_image"]) || array_key_exists("related_image"$context) ? $context["related_image"] : (function () { throw new RuntimeError('Variable "related_image" does not exist.'3355$this->source); })()) && twig_in_filter("1段目画像あり", (isset($context["related_image"]) || array_key_exists("related_image"$context) ? $context["related_image"] : (function () { throw new RuntimeError('Variable "related_image" does not exist.'3355$this->source); })())));
  3985.         // line 3356
  3986.         echo "                        ";
  3987.         $context["img2"] = ((isset($context["related_image"]) || array_key_exists("related_image"$context) ? $context["related_image"] : (function () { throw new RuntimeError('Variable "related_image" does not exist.'3356$this->source); })()) && twig_in_filter("2段目画像あり", (isset($context["related_image"]) || array_key_exists("related_image"$context) ? $context["related_image"] : (function () { throw new RuntimeError('Variable "related_image" does not exist.'3356$this->source); })())));
  3988.         // line 3357
  3989.         echo "                        ";
  3990.         $context["img3"] = ((isset($context["related_image"]) || array_key_exists("related_image"$context) ? $context["related_image"] : (function () { throw new RuntimeError('Variable "related_image" does not exist.'3357$this->source); })()) && twig_in_filter("3段目画像あり", (isset($context["related_image"]) || array_key_exists("related_image"$context) ? $context["related_image"] : (function () { throw new RuntimeError('Variable "related_image" does not exist.'3357$this->source); })())));
  3991.         // line 3358
  3992.         echo "                        ";
  3993.         $context["img4"] = ((isset($context["related_image"]) || array_key_exists("related_image"$context) ? $context["related_image"] : (function () { throw new RuntimeError('Variable "related_image" does not exist.'3358$this->source); })()) && twig_in_filter("4段目画像あり", (isset($context["related_image"]) || array_key_exists("related_image"$context) ? $context["related_image"] : (function () { throw new RuntimeError('Variable "related_image" does not exist.'3358$this->source); })())));
  3994.         // line 3359
  3995.         echo "\t\t\t\t\t    ";
  3996.         $context["type1"] = $this->extensions['Plugin\ProductField\Twig\Extension\EccubeExtension']->getProduct_field(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3359$this->source); })()), "id", [], "any"falsefalsefalse3359), "related_name1");
  3997.         // line 3360
  3998.         echo "\t\t\t\t\t\t";
  3999.         $context["type2"] = $this->extensions['Plugin\ProductField\Twig\Extension\EccubeExtension']->getProduct_field(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3360$this->source); })()), "id", [], "any"falsefalsefalse3360), "related_name2");
  4000.         // line 3361
  4001.         echo "\t\t\t\t\t\t";
  4002.         $context["type3"] = $this->extensions['Plugin\ProductField\Twig\Extension\EccubeExtension']->getProduct_field(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3361$this->source); })()), "id", [], "any"falsefalsefalse3361), "related_name3");
  4003.         // line 3362
  4004.         echo "\t\t\t\t\t\t";
  4005.         $context["type4"] = $this->extensions['Plugin\ProductField\Twig\Extension\EccubeExtension']->getProduct_field(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3362$this->source); })()), "id", [], "any"falsefalsefalse3362), "related_name4");
  4006.         // line 3363
  4007.         echo "\t\t\t\t\t\t";
  4008.         $context["hasRelated"] = ((((((isset($context["type1"]) || array_key_exists("type1"$context) ? $context["type1"] : (function () { throw new RuntimeError('Variable "type1" does not exist.'3363$this->source); })()) && (isset($context["related_product1"]) || array_key_exists("related_product1"$context) ? $context["related_product1"] : (function () { throw new RuntimeError('Variable "related_product1" does not exist.'3363$this->source); })())) && twig_length_filter($this->env, (isset($context["related_product1"]) || array_key_exists("related_product1"$context) ? $context["related_product1"] : (function () { throw new RuntimeError('Variable "related_product1" does not exist.'3363$this->source); })()))) || ((        // line 3364
  4009. (isset($context["type2"]) || array_key_exists("type2"$context) ? $context["type2"] : (function () { throw new RuntimeError('Variable "type2" does not exist.'3364$this->source); })()) && (isset($context["related_product2"]) || array_key_exists("related_product2"$context) ? $context["related_product2"] : (function () { throw new RuntimeError('Variable "related_product2" does not exist.'3364$this->source); })())) && twig_length_filter($this->env, (isset($context["related_product2"]) || array_key_exists("related_product2"$context) ? $context["related_product2"] : (function () { throw new RuntimeError('Variable "related_product2" does not exist.'3364$this->source); })())))) || ((        // line 3365
  4010. (isset($context["type3"]) || array_key_exists("type3"$context) ? $context["type3"] : (function () { throw new RuntimeError('Variable "type3" does not exist.'3365$this->source); })()) && (isset($context["related_product3"]) || array_key_exists("related_product3"$context) ? $context["related_product3"] : (function () { throw new RuntimeError('Variable "related_product3" does not exist.'3365$this->source); })())) && twig_length_filter($this->env, (isset($context["related_product3"]) || array_key_exists("related_product3"$context) ? $context["related_product3"] : (function () { throw new RuntimeError('Variable "related_product3" does not exist.'3365$this->source); })())))) || ((        // line 3366
  4011. (isset($context["type4"]) || array_key_exists("type4"$context) ? $context["type4"] : (function () { throw new RuntimeError('Variable "type4" does not exist.'3366$this->source); })()) && (isset($context["related_product4"]) || array_key_exists("related_product4"$context) ? $context["related_product4"] : (function () { throw new RuntimeError('Variable "related_product4" does not exist.'3366$this->source); })())) && twig_length_filter($this->env, (isset($context["related_product4"]) || array_key_exists("related_product4"$context) ? $context["related_product4"] : (function () { throw new RuntimeError('Variable "related_product4" does not exist.'3366$this->source); })()))));
  4012.         // line 3367
  4013.         echo "\t\t\t\t\t\t";
  4014.         if ((isset($context["hasRelated"]) || array_key_exists("hasRelated"$context) ? $context["hasRelated"] : (function () { throw new RuntimeError('Variable "hasRelated" does not exist.'3367$this->source); })())) {
  4015.             // line 3368
  4016.             echo "\t\t\t\t\t\t    <div class=\"row\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\"><label class=\"col-12 col-form-label\">この商品のタイプを選択してください。</label></div>
  4017. \t\t\t\t\t\t";
  4018.         }
  4019.         // line 3370
  4020.         echo "
  4021. \t\t\t\t\t\t";
  4022.         // line 3372
  4023.         echo "\t\t\t\t\t\t";
  4024.         if ((((isset($context["type1"]) || array_key_exists("type1"$context) ? $context["type1"] : (function () { throw new RuntimeError('Variable "type1" does not exist.'3372$this->source); })()) && (isset($context["related_product1"]) || array_key_exists("related_product1"$context) ? $context["related_product1"] : (function () { throw new RuntimeError('Variable "related_product1" does not exist.'3372$this->source); })())) && twig_length_filter($this->env, (isset($context["related_product1"]) || array_key_exists("related_product1"$context) ? $context["related_product1"] : (function () { throw new RuntimeError('Variable "related_product1" does not exist.'3372$this->source); })())))) {
  4025.             // line 3373
  4026.             echo "\t\t\t\t\t\t<div class=\"form-group mt-3 pb-3\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  4027. \t\t\t\t\t\t  <div class=\"rp-section-label\">";
  4028.             // line 3374
  4029.             echo twig_escape_filter($this->env, (isset($context["type1"]) || array_key_exists("type1"$context) ? $context["type1"] : (function () { throw new RuntimeError('Variable "type1" does not exist.'3374$this->source); })()), "html"nulltrue);
  4030.             if (((isset($context["img1"]) || array_key_exists("img1"$context) ? $context["img1"] : (function () { throw new RuntimeError('Variable "img1" does not exist.'3374$this->source); })()) && (isset($context["base_select1"]) || array_key_exists("base_select1"$context) ? $context["base_select1"] : (function () { throw new RuntimeError('Variable "base_select1" does not exist.'3374$this->source); })()))) {
  4031.                 echo ": <span>";
  4032.                 echo twig_escape_filter($this->env, (isset($context["base_select1"]) || array_key_exists("base_select1"$context) ? $context["base_select1"] : (function () { throw new RuntimeError('Variable "base_select1" does not exist.'3374$this->source); })()), "html"nulltrue);
  4033.                 echo "</span>";
  4034.             }
  4035.             echo "</div>
  4036. \t\t\t\t\t\t  ";
  4037.             // line 3375
  4038.             if ((isset($context["img1"]) || array_key_exists("img1"$context) ? $context["img1"] : (function () { throw new RuntimeError('Variable "img1" does not exist.'3375$this->source); })())) {
  4039.                 // line 3376
  4040.                 echo "\t\t\t\t\t\t    ";
  4041.                 // line 3377
  4042.                 echo "\t\t\t\t\t\t    <div class=\"rp-card-group\">
  4043. \t\t\t\t\t\t      ";
  4044.                 // line 3378
  4045.                 $context['_parent'] = $context;
  4046.                 $context['_seq'] = twig_ensure_traversable((isset($context["related_product1"]) || array_key_exists("related_product1"$context) ? $context["related_product1"] : (function () { throw new RuntimeError('Variable "related_product1" does not exist.'3378$this->source); })()));
  4047.                 foreach ($context['_seq'] as $context["rp_id"] => $context["rp_name"]) {
  4048.                     // line 3379
  4049.                     echo "\t\t\t\t\t\t        <a class=\"rp-card";
  4050.                     if (((isset($context["base_select1"]) || array_key_exists("base_select1"$context) ? $context["base_select1"] : (function () { throw new RuntimeError('Variable "base_select1" does not exist.'3379$this->source); })()) == $context["rp_name"])) {
  4051.                         echo " is-selected";
  4052.                     }
  4053.                     echo "\" href=\"/products/detail/";
  4054.                     echo twig_escape_filter($this->env$context["rp_id"], "html"nulltrue);
  4055.                     echo "\">
  4056. \t\t\t\t\t\t          <img class=\"rp-card__image\"
  4057. \t\t\t\t\t\t               src=\"";
  4058.                     // line 3381
  4059.                     echo twig_escape_filter($this->env, (((twig_get_attribute($this->env$this->source, ($context["related_image_obj"] ?? null), $context["rp_id"], [], "array"truetruefalse3381) && twig_get_attribute($this->env$this->source, (isset($context["related_image_obj"]) || array_key_exists("related_image_obj"$context) ? $context["related_image_obj"] : (function () { throw new RuntimeError('Variable "related_image_obj" does not exist.'3381$this->source); })()), $context["rp_id"], [], "array"falsefalsefalse3381))) ? ($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl(twig_get_attribute($this->env$this->source, (isset($context["related_image_obj"]) || array_key_exists("related_image_obj"$context) ? $context["related_image_obj"] : (function () { throw new RuntimeError('Variable "related_image_obj" does not exist.'3381$this->source); })()), $context["rp_id"], [], "array"falsefalsefalse3381), "save_image")) : ($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl($this->extensions['Eccube\Twig\Extension\EccubeExtension']->getNoImageProduct(""), "save_image"))), "html"nulltrue);
  4060.                     echo "\"
  4061. \t\t\t\t\t\t               alt=\"";
  4062.                     // line 3382
  4063.                     echo twig_escape_filter($this->env$context["rp_name"], "html"nulltrue);
  4064.                     echo "\"
  4065. \t\t\t\t\t\t               width=\"120\" height=\"120\" loading=\"lazy\"
  4066. \t\t\t\t\t\t               onerror=\"this.style.display='none';this.nextElementSibling.style.display='flex';\">
  4067. \t\t\t\t\t\t          <div class=\"rp-card__placeholder\" style=\"display:none;\">📦</div>
  4068. \t\t\t\t\t\t          <span class=\"rp-card__name\">";
  4069.                     // line 3386
  4070.                     echo twig_escape_filter($this->env$context["rp_name"], "html"nulltrue);
  4071.                     echo "</span>
  4072. \t\t\t\t\t\t        </a>
  4073. \t\t\t\t\t\t      ";
  4074.                 }
  4075.                 $_parent $context['_parent'];
  4076.                 unset($context['_seq'], $context['_iterated'], $context['rp_id'], $context['rp_name'], $context['_parent'], $context['loop']);
  4077.                 $context array_intersect_key($context$_parent) + $_parent;
  4078.                 // line 3389
  4079.                 echo "\t\t\t\t\t\t    </div>
  4080. \t\t\t\t\t\t  ";
  4081.             } else {
  4082.                 // line 3391
  4083.                 echo "\t\t\t\t\t\t    ";
  4084.                 // line 3392
  4085.                 echo "\t\t\t\t\t\t    <div class=\"rp-btn-group\">
  4086. \t\t\t\t\t\t      ";
  4087.                 // line 3393
  4088.                 $context['_parent'] = $context;
  4089.                 $context['_seq'] = twig_ensure_traversable((isset($context["related_product1"]) || array_key_exists("related_product1"$context) ? $context["related_product1"] : (function () { throw new RuntimeError('Variable "related_product1" does not exist.'3393$this->source); })()));
  4090.                 foreach ($context['_seq'] as $context["rp_id"] => $context["rp_name"]) {
  4091.                     // line 3394
  4092.                     echo "\t\t\t\t\t\t        <a class=\"rp-btn";
  4093.                     if (((isset($context["base_select1"]) || array_key_exists("base_select1"$context) ? $context["base_select1"] : (function () { throw new RuntimeError('Variable "base_select1" does not exist.'3394$this->source); })()) == $context["rp_name"])) {
  4094.                         echo " is-selected";
  4095.                     }
  4096.                     echo "\" href=\"/products/detail/";
  4097.                     echo twig_escape_filter($this->env$context["rp_id"], "html"nulltrue);
  4098.                     echo "\">
  4099. \t\t\t\t\t\t          ";
  4100.                     // line 3395
  4101.                     echo twig_escape_filter($this->env$context["rp_name"], "html"nulltrue);
  4102.                     echo "
  4103. \t\t\t\t\t\t        </a>
  4104. \t\t\t\t\t\t      ";
  4105.                 }
  4106.                 $_parent $context['_parent'];
  4107.                 unset($context['_seq'], $context['_iterated'], $context['rp_id'], $context['rp_name'], $context['_parent'], $context['loop']);
  4108.                 $context array_intersect_key($context$_parent) + $_parent;
  4109.                 // line 3398
  4110.                 echo "\t\t\t\t\t\t    </div>
  4111. \t\t\t\t\t\t  ";
  4112.             }
  4113.             // line 3400
  4114.             echo "\t\t\t\t\t\t</div>
  4115. \t\t\t\t\t\t";
  4116.         }
  4117.         // line 3402
  4118.         echo "
  4119. \t\t\t\t\t\t";
  4120.         // line 3404
  4121.         echo "\t\t\t\t\t\t";
  4122.         if ((((isset($context["type2"]) || array_key_exists("type2"$context) ? $context["type2"] : (function () { throw new RuntimeError('Variable "type2" does not exist.'3404$this->source); })()) && (isset($context["related_product2"]) || array_key_exists("related_product2"$context) ? $context["related_product2"] : (function () { throw new RuntimeError('Variable "related_product2" does not exist.'3404$this->source); })())) && twig_length_filter($this->env, (isset($context["related_product2"]) || array_key_exists("related_product2"$context) ? $context["related_product2"] : (function () { throw new RuntimeError('Variable "related_product2" does not exist.'3404$this->source); })())))) {
  4123.             // line 3405
  4124.             echo "\t\t\t\t\t\t<div class=\"form-group mt-3 pb-3\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  4125. \t\t\t\t\t\t  <div class=\"rp-section-label\">";
  4126.             // line 3406
  4127.             echo twig_escape_filter($this->env, (isset($context["type2"]) || array_key_exists("type2"$context) ? $context["type2"] : (function () { throw new RuntimeError('Variable "type2" does not exist.'3406$this->source); })()), "html"nulltrue);
  4128.             if (((isset($context["img2"]) || array_key_exists("img2"$context) ? $context["img2"] : (function () { throw new RuntimeError('Variable "img2" does not exist.'3406$this->source); })()) && (isset($context["base_select2"]) || array_key_exists("base_select2"$context) ? $context["base_select2"] : (function () { throw new RuntimeError('Variable "base_select2" does not exist.'3406$this->source); })()))) {
  4129.                 echo ": <span>";
  4130.                 echo twig_escape_filter($this->env, (isset($context["base_select2"]) || array_key_exists("base_select2"$context) ? $context["base_select2"] : (function () { throw new RuntimeError('Variable "base_select2" does not exist.'3406$this->source); })()), "html"nulltrue);
  4131.                 echo "</span>";
  4132.             }
  4133.             echo "</div>
  4134. \t\t\t\t\t\t  ";
  4135.             // line 3407
  4136.             if ((isset($context["img2"]) || array_key_exists("img2"$context) ? $context["img2"] : (function () { throw new RuntimeError('Variable "img2" does not exist.'3407$this->source); })())) {
  4137.                 // line 3408
  4138.                 echo "\t\t\t\t\t\t    <div class=\"rp-card-group\">
  4139. \t\t\t\t\t\t      ";
  4140.                 // line 3409
  4141.                 $context['_parent'] = $context;
  4142.                 $context['_seq'] = twig_ensure_traversable((isset($context["related_product2"]) || array_key_exists("related_product2"$context) ? $context["related_product2"] : (function () { throw new RuntimeError('Variable "related_product2" does not exist.'3409$this->source); })()));
  4143.                 foreach ($context['_seq'] as $context["rp_id"] => $context["rp_name"]) {
  4144.                     // line 3410
  4145.                     echo "\t\t\t\t\t\t        <a class=\"rp-card";
  4146.                     if (((isset($context["base_select2"]) || array_key_exists("base_select2"$context) ? $context["base_select2"] : (function () { throw new RuntimeError('Variable "base_select2" does not exist.'3410$this->source); })()) == $context["rp_name"])) {
  4147.                         echo " is-selected";
  4148.                     }
  4149.                     echo "\" href=\"/products/detail/";
  4150.                     echo twig_escape_filter($this->env$context["rp_id"], "html"nulltrue);
  4151.                     echo "\">
  4152. \t\t\t\t\t\t          <img class=\"rp-card__image\"
  4153. \t\t\t\t\t\t               src=\"";
  4154.                     // line 3412
  4155.                     echo twig_escape_filter($this->env, (((twig_get_attribute($this->env$this->source, ($context["related_image_obj"] ?? null), $context["rp_id"], [], "array"truetruefalse3412) && twig_get_attribute($this->env$this->source, (isset($context["related_image_obj"]) || array_key_exists("related_image_obj"$context) ? $context["related_image_obj"] : (function () { throw new RuntimeError('Variable "related_image_obj" does not exist.'3412$this->source); })()), $context["rp_id"], [], "array"falsefalsefalse3412))) ? ($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl(twig_get_attribute($this->env$this->source, (isset($context["related_image_obj"]) || array_key_exists("related_image_obj"$context) ? $context["related_image_obj"] : (function () { throw new RuntimeError('Variable "related_image_obj" does not exist.'3412$this->source); })()), $context["rp_id"], [], "array"falsefalsefalse3412), "save_image")) : ($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl($this->extensions['Eccube\Twig\Extension\EccubeExtension']->getNoImageProduct(""), "save_image"))), "html"nulltrue);
  4156.                     echo "\"
  4157. \t\t\t\t\t\t               alt=\"";
  4158.                     // line 3413
  4159.                     echo twig_escape_filter($this->env$context["rp_name"], "html"nulltrue);
  4160.                     echo "\"
  4161. \t\t\t\t\t\t               width=\"120\" height=\"120\" loading=\"lazy\"
  4162. \t\t\t\t\t\t               onerror=\"this.style.display='none';this.nextElementSibling.style.display='flex';\">
  4163. \t\t\t\t\t\t          <div class=\"rp-card__placeholder\" style=\"display:none;\">📦</div>
  4164. \t\t\t\t\t\t          <span class=\"rp-card__name\">";
  4165.                     // line 3417
  4166.                     echo twig_escape_filter($this->env$context["rp_name"], "html"nulltrue);
  4167.                     echo "</span>
  4168. \t\t\t\t\t\t        </a>
  4169. \t\t\t\t\t\t      ";
  4170.                 }
  4171.                 $_parent $context['_parent'];
  4172.                 unset($context['_seq'], $context['_iterated'], $context['rp_id'], $context['rp_name'], $context['_parent'], $context['loop']);
  4173.                 $context array_intersect_key($context$_parent) + $_parent;
  4174.                 // line 3420
  4175.                 echo "\t\t\t\t\t\t    </div>
  4176. \t\t\t\t\t\t  ";
  4177.             } else {
  4178.                 // line 3422
  4179.                 echo "\t\t\t\t\t\t    <div class=\"rp-btn-group\">
  4180. \t\t\t\t\t\t      ";
  4181.                 // line 3423
  4182.                 $context['_parent'] = $context;
  4183.                 $context['_seq'] = twig_ensure_traversable((isset($context["related_product2"]) || array_key_exists("related_product2"$context) ? $context["related_product2"] : (function () { throw new RuntimeError('Variable "related_product2" does not exist.'3423$this->source); })()));
  4184.                 foreach ($context['_seq'] as $context["rp_id"] => $context["rp_name"]) {
  4185.                     // line 3424
  4186.                     echo "\t\t\t\t\t\t        <a class=\"rp-btn";
  4187.                     if (((isset($context["base_select2"]) || array_key_exists("base_select2"$context) ? $context["base_select2"] : (function () { throw new RuntimeError('Variable "base_select2" does not exist.'3424$this->source); })()) == $context["rp_name"])) {
  4188.                         echo " is-selected";
  4189.                     }
  4190.                     echo "\" href=\"/products/detail/";
  4191.                     echo twig_escape_filter($this->env$context["rp_id"], "html"nulltrue);
  4192.                     echo "\">
  4193. \t\t\t\t\t\t          ";
  4194.                     // line 3425
  4195.                     echo twig_escape_filter($this->env$context["rp_name"], "html"nulltrue);
  4196.                     echo "
  4197. \t\t\t\t\t\t        </a>
  4198. \t\t\t\t\t\t      ";
  4199.                 }
  4200.                 $_parent $context['_parent'];
  4201.                 unset($context['_seq'], $context['_iterated'], $context['rp_id'], $context['rp_name'], $context['_parent'], $context['loop']);
  4202.                 $context array_intersect_key($context$_parent) + $_parent;
  4203.                 // line 3428
  4204.                 echo "\t\t\t\t\t\t    </div>
  4205. \t\t\t\t\t\t  ";
  4206.             }
  4207.             // line 3430
  4208.             echo "\t\t\t\t\t\t</div>
  4209. \t\t\t\t\t\t";
  4210.         }
  4211.         // line 3432
  4212.         echo "
  4213. \t\t\t\t\t\t";
  4214.         // line 3434
  4215.         echo "\t\t\t\t\t\t";
  4216.         if ((((isset($context["type3"]) || array_key_exists("type3"$context) ? $context["type3"] : (function () { throw new RuntimeError('Variable "type3" does not exist.'3434$this->source); })()) && (isset($context["related_product3"]) || array_key_exists("related_product3"$context) ? $context["related_product3"] : (function () { throw new RuntimeError('Variable "related_product3" does not exist.'3434$this->source); })())) && twig_length_filter($this->env, (isset($context["related_product3"]) || array_key_exists("related_product3"$context) ? $context["related_product3"] : (function () { throw new RuntimeError('Variable "related_product3" does not exist.'3434$this->source); })())))) {
  4217.             // line 3435
  4218.             echo "\t\t\t\t\t\t<div class=\"form-group mt-3 pb-3\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  4219. \t\t\t\t\t\t  <div class=\"rp-section-label\">";
  4220.             // line 3436
  4221.             echo twig_escape_filter($this->env, (isset($context["type3"]) || array_key_exists("type3"$context) ? $context["type3"] : (function () { throw new RuntimeError('Variable "type3" does not exist.'3436$this->source); })()), "html"nulltrue);
  4222.             if (((isset($context["img3"]) || array_key_exists("img3"$context) ? $context["img3"] : (function () { throw new RuntimeError('Variable "img3" does not exist.'3436$this->source); })()) && (isset($context["base_select3"]) || array_key_exists("base_select3"$context) ? $context["base_select3"] : (function () { throw new RuntimeError('Variable "base_select3" does not exist.'3436$this->source); })()))) {
  4223.                 echo ": <span>";
  4224.                 echo twig_escape_filter($this->env, (isset($context["base_select3"]) || array_key_exists("base_select3"$context) ? $context["base_select3"] : (function () { throw new RuntimeError('Variable "base_select3" does not exist.'3436$this->source); })()), "html"nulltrue);
  4225.                 echo "</span>";
  4226.             }
  4227.             echo "</div>
  4228. \t\t\t\t\t\t  ";
  4229.             // line 3437
  4230.             if ((isset($context["img3"]) || array_key_exists("img3"$context) ? $context["img3"] : (function () { throw new RuntimeError('Variable "img3" does not exist.'3437$this->source); })())) {
  4231.                 // line 3438
  4232.                 echo "\t\t\t\t\t\t    <div class=\"rp-card-group\">
  4233. \t\t\t\t\t\t      ";
  4234.                 // line 3439
  4235.                 $context['_parent'] = $context;
  4236.                 $context['_seq'] = twig_ensure_traversable((isset($context["related_product3"]) || array_key_exists("related_product3"$context) ? $context["related_product3"] : (function () { throw new RuntimeError('Variable "related_product3" does not exist.'3439$this->source); })()));
  4237.                 foreach ($context['_seq'] as $context["rp_id"] => $context["rp_name"]) {
  4238.                     // line 3440
  4239.                     echo "\t\t\t\t\t\t        <a class=\"rp-card";
  4240.                     if (((isset($context["base_select3"]) || array_key_exists("base_select3"$context) ? $context["base_select3"] : (function () { throw new RuntimeError('Variable "base_select3" does not exist.'3440$this->source); })()) == $context["rp_name"])) {
  4241.                         echo " is-selected";
  4242.                     }
  4243.                     echo "\" href=\"/products/detail/";
  4244.                     echo twig_escape_filter($this->env$context["rp_id"], "html"nulltrue);
  4245.                     echo "\">
  4246. \t\t\t\t\t\t          <img class=\"rp-card__image\"
  4247. \t\t\t\t\t\t               src=\"";
  4248.                     // line 3442
  4249.                     echo twig_escape_filter($this->env, (((twig_get_attribute($this->env$this->source, ($context["related_image_obj"] ?? null), $context["rp_id"], [], "array"truetruefalse3442) && twig_get_attribute($this->env$this->source, (isset($context["related_image_obj"]) || array_key_exists("related_image_obj"$context) ? $context["related_image_obj"] : (function () { throw new RuntimeError('Variable "related_image_obj" does not exist.'3442$this->source); })()), $context["rp_id"], [], "array"falsefalsefalse3442))) ? ($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl(twig_get_attribute($this->env$this->source, (isset($context["related_image_obj"]) || array_key_exists("related_image_obj"$context) ? $context["related_image_obj"] : (function () { throw new RuntimeError('Variable "related_image_obj" does not exist.'3442$this->source); })()), $context["rp_id"], [], "array"falsefalsefalse3442), "save_image")) : ($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl($this->extensions['Eccube\Twig\Extension\EccubeExtension']->getNoImageProduct(""), "save_image"))), "html"nulltrue);
  4250.                     echo "\"
  4251. \t\t\t\t\t\t               alt=\"";
  4252.                     // line 3443
  4253.                     echo twig_escape_filter($this->env$context["rp_name"], "html"nulltrue);
  4254.                     echo "\"
  4255. \t\t\t\t\t\t               width=\"120\" height=\"120\" loading=\"lazy\"
  4256. \t\t\t\t\t\t               onerror=\"this.style.display='none';this.nextElementSibling.style.display='flex';\">
  4257. \t\t\t\t\t\t          <div class=\"rp-card__placeholder\" style=\"display:none;\">📦</div>
  4258. \t\t\t\t\t\t          <span class=\"rp-card__name\">";
  4259.                     // line 3447
  4260.                     echo twig_escape_filter($this->env$context["rp_name"], "html"nulltrue);
  4261.                     echo "</span>
  4262. \t\t\t\t\t\t        </a>
  4263. \t\t\t\t\t\t      ";
  4264.                 }
  4265.                 $_parent $context['_parent'];
  4266.                 unset($context['_seq'], $context['_iterated'], $context['rp_id'], $context['rp_name'], $context['_parent'], $context['loop']);
  4267.                 $context array_intersect_key($context$_parent) + $_parent;
  4268.                 // line 3450
  4269.                 echo "\t\t\t\t\t\t    </div>
  4270. \t\t\t\t\t\t  ";
  4271.             } else {
  4272.                 // line 3452
  4273.                 echo "\t\t\t\t\t\t    <div class=\"rp-btn-group\">
  4274. \t\t\t\t\t\t      ";
  4275.                 // line 3453
  4276.                 $context['_parent'] = $context;
  4277.                 $context['_seq'] = twig_ensure_traversable((isset($context["related_product3"]) || array_key_exists("related_product3"$context) ? $context["related_product3"] : (function () { throw new RuntimeError('Variable "related_product3" does not exist.'3453$this->source); })()));
  4278.                 foreach ($context['_seq'] as $context["rp_id"] => $context["rp_name"]) {
  4279.                     // line 3454
  4280.                     echo "\t\t\t\t\t\t        <a class=\"rp-btn";
  4281.                     if (((isset($context["base_select3"]) || array_key_exists("base_select3"$context) ? $context["base_select3"] : (function () { throw new RuntimeError('Variable "base_select3" does not exist.'3454$this->source); })()) == $context["rp_name"])) {
  4282.                         echo " is-selected";
  4283.                     }
  4284.                     echo "\" href=\"/products/detail/";
  4285.                     echo twig_escape_filter($this->env$context["rp_id"], "html"nulltrue);
  4286.                     echo "\">
  4287. \t\t\t\t\t\t          ";
  4288.                     // line 3455
  4289.                     echo twig_escape_filter($this->env$context["rp_name"], "html"nulltrue);
  4290.                     echo "
  4291. \t\t\t\t\t\t        </a>
  4292. \t\t\t\t\t\t      ";
  4293.                 }
  4294.                 $_parent $context['_parent'];
  4295.                 unset($context['_seq'], $context['_iterated'], $context['rp_id'], $context['rp_name'], $context['_parent'], $context['loop']);
  4296.                 $context array_intersect_key($context$_parent) + $_parent;
  4297.                 // line 3458
  4298.                 echo "\t\t\t\t\t\t    </div>
  4299. \t\t\t\t\t\t  ";
  4300.             }
  4301.             // line 3460
  4302.             echo "\t\t\t\t\t\t</div>
  4303. \t\t\t\t\t\t";
  4304.         }
  4305.         // line 3462
  4306.         echo "
  4307. \t\t\t\t\t\t";
  4308.         // line 3464
  4309.         echo "\t\t\t\t\t\t";
  4310.         if ((((isset($context["type4"]) || array_key_exists("type4"$context) ? $context["type4"] : (function () { throw new RuntimeError('Variable "type4" does not exist.'3464$this->source); })()) && (isset($context["related_product4"]) || array_key_exists("related_product4"$context) ? $context["related_product4"] : (function () { throw new RuntimeError('Variable "related_product4" does not exist.'3464$this->source); })())) && twig_length_filter($this->env, (isset($context["related_product4"]) || array_key_exists("related_product4"$context) ? $context["related_product4"] : (function () { throw new RuntimeError('Variable "related_product4" does not exist.'3464$this->source); })())))) {
  4311.             // line 3465
  4312.             echo "\t\t\t\t\t\t<div class=\"form-group mt-3 pb-3\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  4313. \t\t\t\t\t\t  <div class=\"rp-section-label\">";
  4314.             // line 3466
  4315.             echo twig_escape_filter($this->env, (isset($context["type4"]) || array_key_exists("type4"$context) ? $context["type4"] : (function () { throw new RuntimeError('Variable "type4" does not exist.'3466$this->source); })()), "html"nulltrue);
  4316.             if (((isset($context["img4"]) || array_key_exists("img4"$context) ? $context["img4"] : (function () { throw new RuntimeError('Variable "img4" does not exist.'3466$this->source); })()) && (isset($context["base_select4"]) || array_key_exists("base_select4"$context) ? $context["base_select4"] : (function () { throw new RuntimeError('Variable "base_select4" does not exist.'3466$this->source); })()))) {
  4317.                 echo ": <span>";
  4318.                 echo twig_escape_filter($this->env, (isset($context["base_select4"]) || array_key_exists("base_select4"$context) ? $context["base_select4"] : (function () { throw new RuntimeError('Variable "base_select4" does not exist.'3466$this->source); })()), "html"nulltrue);
  4319.                 echo "</span>";
  4320.             }
  4321.             echo "</div>
  4322. \t\t\t\t\t\t  ";
  4323.             // line 3467
  4324.             if ((isset($context["img4"]) || array_key_exists("img4"$context) ? $context["img4"] : (function () { throw new RuntimeError('Variable "img4" does not exist.'3467$this->source); })())) {
  4325.                 // line 3468
  4326.                 echo "\t\t\t\t\t\t    ";
  4327.                 // line 3469
  4328.                 echo "\t\t\t\t\t\t    <div class=\"rp-card-group\">
  4329. \t\t\t\t\t\t      ";
  4330.                 // line 3470
  4331.                 $context['_parent'] = $context;
  4332.                 $context['_seq'] = twig_ensure_traversable((isset($context["related_product4"]) || array_key_exists("related_product4"$context) ? $context["related_product4"] : (function () { throw new RuntimeError('Variable "related_product4" does not exist.'3470$this->source); })()));
  4333.                 foreach ($context['_seq'] as $context["rp_id"] => $context["rp_name"]) {
  4334.                     // line 3471
  4335.                     echo "\t\t\t\t\t\t        <a class=\"rp-card";
  4336.                     if (((isset($context["base_select4"]) || array_key_exists("base_select4"$context) ? $context["base_select4"] : (function () { throw new RuntimeError('Variable "base_select4" does not exist.'3471$this->source); })()) == $context["rp_name"])) {
  4337.                         echo " is-selected";
  4338.                     }
  4339.                     echo "\" href=\"/products/detail/";
  4340.                     echo twig_escape_filter($this->env$context["rp_id"], "html"nulltrue);
  4341.                     echo "\">
  4342. \t\t\t\t\t\t          <img class=\"rp-card__image\"
  4343. \t\t\t\t\t\t               src=\"";
  4344.                     // line 3473
  4345.                     echo twig_escape_filter($this->env, (((twig_get_attribute($this->env$this->source, ($context["related_image_obj"] ?? null), $context["rp_id"], [], "array"truetruefalse3473) && twig_get_attribute($this->env$this->source, (isset($context["related_image_obj"]) || array_key_exists("related_image_obj"$context) ? $context["related_image_obj"] : (function () { throw new RuntimeError('Variable "related_image_obj" does not exist.'3473$this->source); })()), $context["rp_id"], [], "array"falsefalsefalse3473))) ? ($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl(twig_get_attribute($this->env$this->source, (isset($context["related_image_obj"]) || array_key_exists("related_image_obj"$context) ? $context["related_image_obj"] : (function () { throw new RuntimeError('Variable "related_image_obj" does not exist.'3473$this->source); })()), $context["rp_id"], [], "array"falsefalsefalse3473), "save_image")) : ($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl($this->extensions['Eccube\Twig\Extension\EccubeExtension']->getNoImageProduct(""), "save_image"))), "html"nulltrue);
  4346.                     echo "\"
  4347. \t\t\t\t\t\t               alt=\"";
  4348.                     // line 3474
  4349.                     echo twig_escape_filter($this->env$context["rp_name"], "html"nulltrue);
  4350.                     echo "\" width=\"120\" height=\"120\" loading=\"lazy\">
  4351. \t\t\t\t\t\t          <span class=\"rp-card__label\">";
  4352.                     // line 3475
  4353.                     echo twig_escape_filter($this->env$context["rp_name"], "html"nulltrue);
  4354.                     echo "</span>
  4355. \t\t\t\t\t\t        </a>
  4356. \t\t\t\t\t\t      ";
  4357.                 }
  4358.                 $_parent $context['_parent'];
  4359.                 unset($context['_seq'], $context['_iterated'], $context['rp_id'], $context['rp_name'], $context['_parent'], $context['loop']);
  4360.                 $context array_intersect_key($context$_parent) + $_parent;
  4361.                 // line 3478
  4362.                 echo "\t\t\t\t\t\t    </div>
  4363. \t\t\t\t\t\t  ";
  4364.             } else {
  4365.                 // line 3480
  4366.                 echo "\t\t\t\t\t\t    ";
  4367.                 // line 3481
  4368.                 echo "\t\t\t\t\t\t    <div class=\"rp-btn-group\">
  4369. \t\t\t\t\t\t      ";
  4370.                 // line 3482
  4371.                 $context['_parent'] = $context;
  4372.                 $context['_seq'] = twig_ensure_traversable((isset($context["related_product4"]) || array_key_exists("related_product4"$context) ? $context["related_product4"] : (function () { throw new RuntimeError('Variable "related_product4" does not exist.'3482$this->source); })()));
  4373.                 foreach ($context['_seq'] as $context["rp_id"] => $context["rp_name"]) {
  4374.                     // line 3483
  4375.                     echo "\t\t\t\t\t\t        <a class=\"rp-btn";
  4376.                     if (((isset($context["base_select4"]) || array_key_exists("base_select4"$context) ? $context["base_select4"] : (function () { throw new RuntimeError('Variable "base_select4" does not exist.'3483$this->source); })()) == $context["rp_name"])) {
  4377.                         echo " is-selected";
  4378.                     }
  4379.                     echo "\" href=\"/products/detail/";
  4380.                     echo twig_escape_filter($this->env$context["rp_id"], "html"nulltrue);
  4381.                     echo "\">
  4382. \t\t\t\t\t\t          ";
  4383.                     // line 3484
  4384.                     echo twig_escape_filter($this->env$context["rp_name"], "html"nulltrue);
  4385.                     echo "
  4386. \t\t\t\t\t\t        </a>
  4387. \t\t\t\t\t\t      ";
  4388.                 }
  4389.                 $_parent $context['_parent'];
  4390.                 unset($context['_seq'], $context['_iterated'], $context['rp_id'], $context['rp_name'], $context['_parent'], $context['loop']);
  4391.                 $context array_intersect_key($context$_parent) + $_parent;
  4392.                 // line 3487
  4393.                 echo "\t\t\t\t\t\t    </div>
  4394. \t\t\t\t\t\t  ";
  4395.             }
  4396.             // line 3489
  4397.             echo "\t\t\t\t\t\t</div>
  4398. \t\t\t\t\t\t";
  4399.         }
  4400.         // line 3491
  4401.         echo "
  4402. \t\t\t\t\t    ";
  4403.         // line 3500
  4404.         echo "\t\t\t\t\t    ";
  4405.         $context["is_gs_h"] = false;
  4406.         // line 3501
  4407.         echo "\t\t\t\t\t    ";
  4408.         $context["is_cg_h"] = false;
  4409.         // line 3502
  4410.         echo "\t\t\t\t\t    ";
  4411.         if ( !twig_test_empty(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3502$this->source); })()), "ProductCategories", [], "any"falsefalsefalse3502))) {
  4412.             // line 3503
  4413.             echo "\t\t\t\t\t        ";
  4414.             $context['_parent'] = $context;
  4415.             $context['_seq'] = twig_ensure_traversable(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3503$this->source); })()), "ProductCategories", [], "any"falsefalsefalse3503));
  4416.             foreach ($context['_seq'] as $context["_key"] => $context["pc_h"]) {
  4417.                 // line 3504
  4418.                 echo "\t\t\t\t\t            ";
  4419.                 if ((twig_get_attribute($this->env$this->source$context["pc_h"], "category_id", [], "any"falsefalsefalse3504) == 27)) {
  4420.                     $context["is_gs_h"] = true;
  4421.                 }
  4422.                 // line 3505
  4423.                 echo "\t\t\t\t\t            ";
  4424.                 if ((twig_get_attribute($this->env$this->source$context["pc_h"], "category_id", [], "any"falsefalsefalse3505) == 9)) {
  4425.                     $context["is_cg_h"] = true;
  4426.                 }
  4427.                 // line 3506
  4428.                 echo "\t\t\t\t\t        ";
  4429.             }
  4430.             $_parent $context['_parent'];
  4431.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pc_h'], $context['_parent'], $context['loop']);
  4432.             $context array_intersect_key($context$_parent) + $_parent;
  4433.             // line 3507
  4434.             echo "\t\t\t\t\t    ";
  4435.         }
  4436.         // line 3508
  4437.         echo "\t\t\t\t\t    ";
  4438.         $context["visible_op_count"] = 0;
  4439.         // line 3509
  4440.         echo "\t\t\t\t\t    ";
  4441.         if (((isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'3509$this->source); })()) && twig_length_filter($this->env, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'3509$this->source); })())))) {
  4442.             // line 3510
  4443.             echo "\t\t\t\t\t        ";
  4444.             $context['_parent'] = $context;
  4445.             $context['_seq'] = twig_ensure_traversable((isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'3510$this->source); })()));
  4446.             foreach ($context['_seq'] as $context["_key"] => $context["opi"]) {
  4447.                 // line 3511
  4448.                 echo "\t\t\t\t\t            ";
  4449.                 if (twig_get_attribute($this->env$this->source$context["opi"], "name", [], "array"falsefalsefalse3511)) {
  4450.                     // line 3512
  4451.                     echo "\t\t\t\t\t                ";
  4452.                     $context["_hide_h"] = false;
  4453.                     // line 3513
  4454.                     echo "\t\t\t\t\t                ";
  4455.                     if (((isset($context["is_gs_h"]) || array_key_exists("is_gs_h"$context) ? $context["is_gs_h"] : (function () { throw new RuntimeError('Variable "is_gs_h" does not exist.'3513$this->source); })()) && (preg_match("/撤去/"twig_get_attribute($this->env$this->source$context["opi"], "name", [], "array"falsefalsefalse3513)) || preg_match("/残土/"twig_get_attribute($this->env$this->source$context["opi"], "name", [], "array"falsefalsefalse3513))))) {
  4456.                         $context["_hide_h"] = true;
  4457.                     }
  4458.                     // line 3514
  4459.                     echo "\t\t\t\t\t                ";
  4460.                     if (((isset($context["is_cg_h"]) || array_key_exists("is_cg_h"$context) ? $context["is_cg_h"] : (function () { throw new RuntimeError('Variable "is_cg_h" does not exist.'3514$this->source); })()) && preg_match("/残土/"twig_get_attribute($this->env$this->source$context["opi"], "name", [], "array"falsefalsefalse3514)))) {
  4461.                         $context["_hide_h"] = true;
  4462.                     }
  4463.                     // line 3515
  4464.                     echo "\t\t\t\t\t                ";
  4465.                     if ( !(isset($context["_hide_h"]) || array_key_exists("_hide_h"$context) ? $context["_hide_h"] : (function () { throw new RuntimeError('Variable "_hide_h" does not exist.'3515$this->source); })())) {
  4466.                         $context["visible_op_count"] = ((isset($context["visible_op_count"]) || array_key_exists("visible_op_count"$context) ? $context["visible_op_count"] : (function () { throw new RuntimeError('Variable "visible_op_count" does not exist.'3515$this->source); })()) + 1);
  4467.                     }
  4468.                     // line 3516
  4469.                     echo "\t\t\t\t\t            ";
  4470.                 }
  4471.                 // line 3517
  4472.                 echo "\t\t\t\t\t        ";
  4473.             }
  4474.             $_parent $context['_parent'];
  4475.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['opi'], $context['_parent'], $context['loop']);
  4476.             $context array_intersect_key($context$_parent) + $_parent;
  4477.             // line 3518
  4478.             echo "\t\t\t\t\t    ";
  4479.         }
  4480.         // line 3519
  4481.         echo "\t\t\t\t\t    ";
  4482.         $context["has_any_option"] = (((((((((        // line 3520
  4483. (isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'3520$this->source); })()) && twig_length_filter($this->env, (isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'3520$this->source); })()))) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3520$this->source); })()), "SaleType", [], "any"falsefalsefalse3520), "id", [], "any"falsefalsefalse3520) != 3)) || ((        // line 3521
  4484. (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3521$this->source); })()) && twig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3521$this->source); })()))) && (twig_join_filter((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3521$this->source); })())) != ""))) || ((        // line 3522
  4485. (isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3522$this->source); })()) && twig_length_filter($this->env, (isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3522$this->source); })()))) && (twig_join_filter((isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3522$this->source); })())) != ""))) || ((        // line 3523
  4486. (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3523$this->source); })()) && twig_length_filter($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3523$this->source); })()))) && (twig_join_filter((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3523$this->source); })())) != ""))) || ((        // line 3524
  4487. (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3524$this->source); })()) && twig_length_filter($this->env, (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3524$this->source); })()))) && (twig_join_filter((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3524$this->source); })())) != ""))) || ((        // line 3525
  4488. (isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3525$this->source); })()) && twig_length_filter($this->env, (isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3525$this->source); })()))) && (twig_join_filter((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3525$this->source); })())) != ""))) || ((        // line 3526
  4489. (isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'3526$this->source); })()) && twig_length_filter($this->env, (isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'3526$this->source); })()))) && (twig_join_filter((isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'3526$this->source); })())) != ""))) || twig_in_filter(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source,         // line 3527
  4490. (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3527$this->source); })()), "SaleType", [], "any"falsefalsefalse3527), "id", [], "any"falsefalsefalse3527), [=> 2=> 5=> 6=> 7=> 9]));
  4491.         // line 3529
  4492.         echo "\t\t\t\t\t    ";
  4493.         if ((isset($context["has_any_option"]) || array_key_exists("has_any_option"$context) ? $context["has_any_option"] : (function () { throw new RuntimeError('Variable "has_any_option" does not exist.'3529$this->source); })())) {
  4494.             // line 3530
  4495.             echo "\t\t\t\t\t    <div class=\"row\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\"><label class=\"col-12 col-form-label\">この商品のオプションを選択してください。</label></div>
  4496. \t\t\t\t\t    ";
  4497.         }
  4498.         // line 3532
  4499.         echo "
  4500.                         ";
  4501.         // line 3534
  4502.         echo "                        ";
  4503.         if (((((isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'3534$this->source); })()) && twig_length_filter($this->env, (isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'3534$this->source); })()))) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3534$this->source); })()), "SaleType", [], "any"falsefalsefalse3534), "id", [], "any"falsefalsefalse3534) != 3)) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3534$this->source); })()), "SaleType", [], "any"falsefalsefalse3534), "id", [], "any"falsefalsefalse3534) != 2))) {
  4504.             // line 3535
  4505.             echo "                        <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  4506.                           <div class=\"rp-section-label\">カラー";
  4507.             // line 3536
  4508.             if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3536$this->source); })()) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3536$this->source); })()), "pc", [], "any"falsefalsefalse3536))) {
  4509.                 echo ": <span>";
  4510.                 echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3536$this->source); })()), "pc", [], "any"falsefalsefalse3536), "html"nulltrue);
  4511.                 echo "</span>";
  4512.             }
  4513.             echo "</div>
  4514.                           <div class=\"opt-btn-group\">
  4515.                             ";
  4516.             // line 3538
  4517.             $context["idx"] = 0;
  4518.             // line 3539
  4519.             echo "                            ";
  4520.             $context['_parent'] = $context;
  4521.             $context['_seq'] = twig_ensure_traversable((isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'3539$this->source); })()));
  4522.             foreach ($context['_seq'] as $context["_key"] => $context["cc"]) {
  4523.                 if (($context["cc"] && twig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3539))) {
  4524.                     $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3539$this->source); })()) + 1);
  4525.                     // line 3540
  4526.                     echo "                              ";
  4527.                     $context["has_img"] = (twig_get_attribute($this->env$this->source$context["cc"], "img", [], "array"truetruefalse3540) &&  !twig_test_empty(twig_get_attribute($this->env$this->source$context["cc"], "img", [], "array"falsefalsefalse3540)));
  4528.                     // line 3541
  4529.                     echo "                              <label class=\"opt-btn";
  4530.                     if ((isset($context["has_img"]) || array_key_exists("has_img"$context) ? $context["has_img"] : (function () { throw new RuntimeError('Variable "has_img" does not exist.'3541$this->source); })())) {
  4531.                         echo " opt-btn--with-image";
  4532.                     }
  4533.                     if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3541$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3541$this->source); })()), "pc", [], "any"falsefalsefalse3541) == twig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3541))) || (twig_length_filter($this->env, (isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'3541$this->source); })())) == 1))) {
  4534.                         echo " is-selected";
  4535.                     }
  4536.                     echo "\"
  4537.                                      onclick=\"mitsumori_simulation_val('pc', '";
  4538.                     // line 3542
  4539.                     echo twig_escape_filter($this->envtwig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3542), "js"), "html"nulltrue);
  4540.                     echo "');\">
  4541.                                 <input type=\"radio\" name=\"color\" id=\"cc_";
  4542.                     // line 3543
  4543.                     echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3543$this->source); })()), "html"nulltrue);
  4544.                     echo "\" value=\"";
  4545.                     echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3543), "html"nulltrue);
  4546.                     echo "\"
  4547.                                        ";
  4548.                     // line 3544
  4549.                     if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3544$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3544$this->source); })()), "pc", [], "any"falsefalsefalse3544) == twig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3544))) || (twig_length_filter($this->env, (isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'3544$this->source); })())) == 1))) {
  4550.                         echo "checked";
  4551.                     }
  4552.                     echo ">
  4553.                                 ";
  4554.                     // line 3545
  4555.                     if ((isset($context["has_img"]) || array_key_exists("has_img"$context) ? $context["has_img"] : (function () { throw new RuntimeError('Variable "has_img" does not exist.'3545$this->source); })())) {
  4556.                         // line 3546
  4557.                         echo "                                  <img src=\"";
  4558.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "img", [], "array"falsefalsefalse3546), "html"nulltrue);
  4559.                         echo "\" alt=\"";
  4560.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3546), "html"nulltrue);
  4561.                         echo "\" class=\"opt-btn__img\"
  4562.                                        onerror=\"this.parentNode.classList.remove('opt-btn--with-image'); this.remove();\">
  4563.                                   <span class=\"opt-btn__name\">";
  4564.                         // line 3548
  4565.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3548), "html"nulltrue);
  4566.                         echo "</span>
  4567.                                 ";
  4568.                     } else {
  4569.                         // line 3550
  4570.                         echo "                                  ";
  4571.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3550), "html"nulltrue);
  4572.                         echo "
  4573.                                 ";
  4574.                     }
  4575.                     // line 3552
  4576.                     echo "                              </label>
  4577.                             ";
  4578.                 }
  4579.             }
  4580.             $_parent $context['_parent'];
  4581.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['cc'], $context['_parent'], $context['loop']);
  4582.             $context array_intersect_key($context$_parent) + $_parent;
  4583.             // line 3554
  4584.             echo "                          </div>
  4585.                         </div>
  4586.                         ";
  4587.         }
  4588.         // line 3557
  4589.         echo "
  4590.                         ";
  4591.         // line 3562
  4592.         echo "                        ";
  4593.         if (((((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3562$this->source); })()) && twig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3562$this->source); })()))) && (twig_join_filter((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3562$this->source); })())) != "")) && !twig_in_filter(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3562$this->source); })()), "SaleType", [], "any"falsefalsefalse3562), "id", [], "any"falsefalsefalse3562), [=> 2=> 3=> 6]))) {
  4594.             // line 3563
  4595.             echo "                        <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  4596.                           <div class=\"rp-section-label\">幅";
  4597.             // line 3564
  4598.             if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3564$this->source); })()) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3564$this->source); })()), "pw", [], "any"falsefalsefalse3564))) {
  4599.                 echo ": <span>";
  4600.                 echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3564$this->source); })()), "pw", [], "any"falsefalsefalse3564), "html"nulltrue);
  4601.                 echo "</span>";
  4602.             }
  4603.             echo "</div>
  4604.                           <div class=\"opt-btn-group\">
  4605.                             ";
  4606.             // line 3566
  4607.             $context["idx"] = 0;
  4608.             // line 3567
  4609.             echo "                            ";
  4610.             $context['_parent'] = $context;
  4611.             $context['_seq'] = twig_ensure_traversable((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3567$this->source); })()));
  4612.             foreach ($context['_seq'] as $context["_key"] => $context["pw"]) {
  4613.                 if ($context["pw"]) {
  4614.                     $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3567$this->source); })()) + 1);
  4615.                     // line 3568
  4616.                     echo "                              <label class=\"opt-btn";
  4617.                     if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3568$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3568$this->source); })()), "pw", [], "any"falsefalsefalse3568) == $context["pw"])) || (twig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3568$this->source); })())) == 1))) {
  4618.                         echo " is-selected";
  4619.                     }
  4620.                     echo "\"
  4621.                                      onclick=\"mitsumori_simulation_val('pw', '";
  4622.                     // line 3569
  4623.                     echo twig_escape_filter($this->envtwig_escape_filter($this->env$context["pw"], "js"), "html"nulltrue);
  4624.                     echo "');\">
  4625.                                 <input type=\"radio\" name=\"pw\" id=\"pw_";
  4626.                     // line 3570
  4627.                     echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3570$this->source); })()), "html"nulltrue);
  4628.                     echo "\" value=\"";
  4629.                     echo twig_escape_filter($this->env$context["pw"], "html"nulltrue);
  4630.                     echo "\"
  4631.                                        ";
  4632.                     // line 3571
  4633.                     if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3571$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3571$this->source); })()), "pw", [], "any"falsefalsefalse3571) == $context["pw"])) || (twig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3571$this->source); })())) == 1))) {
  4634.                         echo "checked";
  4635.                     }
  4636.                     echo ">
  4637.                                 ";
  4638.                     // line 3572
  4639.                     echo twig_escape_filter($this->env$context["pw"], "html"nulltrue);
  4640.                     echo "
  4641.                               </label>
  4642.                             ";
  4643.                 }
  4644.             }
  4645.             $_parent $context['_parent'];
  4646.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pw'], $context['_parent'], $context['loop']);
  4647.             $context array_intersect_key($context$_parent) + $_parent;
  4648.             // line 3575
  4649.             echo "                          </div>
  4650.                         </div>
  4651.                         ";
  4652.         }
  4653.         // line 3578
  4654.         echo "
  4655.                         ";
  4656.         // line 3579
  4657.         if (((((isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3579$this->source); })()) && twig_length_filter($this->env, (isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3579$this->source); })()))) && (twig_join_filter((isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3579$this->source); })())) != "")) && !twig_in_filter(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3579$this->source); })()), "SaleType", [], "any"falsefalsefalse3579), "id", [], "any"falsefalsefalse3579), [=> 3=> 6]))) {
  4658.             // line 3580
  4659.             echo "                        <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  4660.                           <div class=\"rp-section-label\">奥行き";
  4661.             // line 3581
  4662.             if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3581$this->source); })()) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3581$this->source); })()), "pd", [], "any"falsefalsefalse3581))) {
  4663.                 echo ": <span>";
  4664.                 echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3581$this->source); })()), "pd", [], "any"falsefalsefalse3581), "html"nulltrue);
  4665.                 echo "</span>";
  4666.             }
  4667.             echo "</div>
  4668.                           <div class=\"opt-btn-group\">
  4669.                             ";
  4670.             // line 3583
  4671.             $context["idx"] = 0;
  4672.             // line 3584
  4673.             echo "                            ";
  4674.             $context['_parent'] = $context;
  4675.             $context['_seq'] = twig_ensure_traversable((isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3584$this->source); })()));
  4676.             foreach ($context['_seq'] as $context["_key"] => $context["pd"]) {
  4677.                 if ($context["pd"]) {
  4678.                     $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3584$this->source); })()) + 1);
  4679.                     // line 3585
  4680.                     echo "                              <label class=\"opt-btn";
  4681.                     if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3585$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3585$this->source); })()), "pd", [], "any"falsefalsefalse3585) == $context["pd"])) || (twig_length_filter($this->env, (isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3585$this->source); })())) == 1))) {
  4682.                         echo " is-selected";
  4683.                     }
  4684.                     echo "\"
  4685.                                      onclick=\"mitsumori_simulation_val('pd', '";
  4686.                     // line 3586
  4687.                     echo twig_escape_filter($this->envtwig_escape_filter($this->env$context["pd"], "js"), "html"nulltrue);
  4688.                     echo "');\">
  4689.                                 <input type=\"radio\" name=\"pd\" id=\"pd_";
  4690.                     // line 3587
  4691.                     echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3587$this->source); })()), "html"nulltrue);
  4692.                     echo "\" value=\"";
  4693.                     echo twig_escape_filter($this->env$context["pd"], "html"nulltrue);
  4694.                     echo "\"
  4695.                                        ";
  4696.                     // line 3588
  4697.                     if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3588$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3588$this->source); })()), "pd", [], "any"falsefalsefalse3588) == $context["pd"])) || (twig_length_filter($this->env, (isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3588$this->source); })())) == 1))) {
  4698.                         echo "checked";
  4699.                     }
  4700.                     echo ">
  4701.                                 ";
  4702.                     // line 3589
  4703.                     echo twig_escape_filter($this->env$context["pd"], "html"nulltrue);
  4704.                     echo "
  4705.                               </label>
  4706.                             ";
  4707.                 }
  4708.             }
  4709.             $_parent $context['_parent'];
  4710.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pd'], $context['_parent'], $context['loop']);
  4711.             $context array_intersect_key($context$_parent) + $_parent;
  4712.             // line 3592
  4713.             echo "                          </div>
  4714.                         </div>
  4715.                         ";
  4716.         }
  4717.         // line 3595
  4718.         echo "
  4719.                         ";
  4720.         // line 3598
  4721.         echo "                        ";
  4722.         if (((((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3598$this->source); })()) && twig_length_filter($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3598$this->source); })()))) && (twig_join_filter((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3598$this->source); })())) != "")) && !twig_in_filter(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3598$this->source); })()), "SaleType", [], "any"falsefalsefalse3598), "id", [], "any"falsefalsefalse3598), [=> 2=> 3=> 6]))) {
  4723.             // line 3599
  4724.             echo "                        <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  4725.                           <div class=\"rp-section-label\">高さ";
  4726.             // line 3600
  4727.             if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3600$this->source); })()) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3600$this->source); })()), "ph", [], "any"falsefalsefalse3600))) {
  4728.                 echo ": <span>";
  4729.                 echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3600$this->source); })()), "ph", [], "any"falsefalsefalse3600), "html"nulltrue);
  4730.                 echo "</span>";
  4731.             }
  4732.             echo "</div>
  4733.                           <div class=\"opt-btn-group\">
  4734.                             ";
  4735.             // line 3602
  4736.             $context["idx"] = 0;
  4737.             // line 3603
  4738.             echo "                            ";
  4739.             $context['_parent'] = $context;
  4740.             $context['_seq'] = twig_ensure_traversable((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3603$this->source); })()));
  4741.             foreach ($context['_seq'] as $context["_key"] => $context["ph"]) {
  4742.                 if ($context["ph"]) {
  4743.                     $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3603$this->source); })()) + 1);
  4744.                     // line 3604
  4745.                     echo "                              <label class=\"opt-btn";
  4746.                     if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3604$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3604$this->source); })()), "ph", [], "any"falsefalsefalse3604) == $context["ph"])) || (twig_length_filter($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3604$this->source); })())) == 1))) {
  4747.                         echo " is-selected";
  4748.                     }
  4749.                     echo "\"
  4750.                                      onclick=\"mitsumori_simulation_val('ph', '";
  4751.                     // line 3605
  4752.                     echo twig_escape_filter($this->envtwig_escape_filter($this->env$context["ph"], "js"), "html"nulltrue);
  4753.                     echo "');\">
  4754.                                 <input type=\"radio\" name=\"ph\" id=\"ph_";
  4755.                     // line 3606
  4756.                     echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3606$this->source); })()), "html"nulltrue);
  4757.                     echo "\" value=\"";
  4758.                     echo twig_escape_filter($this->env$context["ph"], "html"nulltrue);
  4759.                     echo "\"
  4760.                                        ";
  4761.                     // line 3607
  4762.                     if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3607$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3607$this->source); })()), "ph", [], "any"falsefalsefalse3607) == $context["ph"])) || (twig_length_filter($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3607$this->source); })())) == 1))) {
  4763.                         echo "checked";
  4764.                     }
  4765.                     echo ">
  4766.                                 ";
  4767.                     // line 3608
  4768.                     echo twig_escape_filter($this->env$context["ph"], "html"nulltrue);
  4769.                     echo "
  4770.                               </label>
  4771.                             ";
  4772.                 }
  4773.             }
  4774.             $_parent $context['_parent'];
  4775.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['ph'], $context['_parent'], $context['loop']);
  4776.             $context array_intersect_key($context$_parent) + $_parent;
  4777.             // line 3611
  4778.             echo "                          </div>
  4779.                         </div>
  4780.                         ";
  4781.         }
  4782.         // line 3614
  4783.         echo "
  4784.                         ";
  4785.         // line 3616
  4786.         echo "                        ";
  4787.         if ((((((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3616$this->source); })()) && twig_length_filter($this->env, (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3616$this->source); })()))) && (twig_join_filter((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3616$this->source); })())) != "")) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3616$this->source); })()), "SaleType", [], "any"falsefalsefalse3616), "id", [], "any"falsefalsefalse3616) != 3)) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3616$this->source); })()), "SaleType", [], "any"falsefalsefalse3616), "id", [], "any"falsefalsefalse3616) != 2))) {
  4788.             // line 3617
  4789.             echo "                        <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  4790.                           <div class=\"rp-section-label\">";
  4791.             // line 3618
  4792.             if ((isset($context["is_cat43"]) || array_key_exists("is_cat43"$context) ? $context["is_cat43"] : (function () { throw new RuntimeError('Variable "is_cat43" does not exist.'3618$this->source); })())) {
  4793.                 echo "開き方";
  4794.             } else {
  4795.                 echo "素材";
  4796.             }
  4797.             if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3618$this->source); })()) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3618$this->source); })()), "pm", [], "any"falsefalsefalse3618))) {
  4798.                 echo ": <span>";
  4799.                 echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3618$this->source); })()), "pm", [], "any"falsefalsefalse3618), "html"nulltrue);
  4800.                 echo "</span>";
  4801.             }
  4802.             echo "</div>
  4803.                           <div class=\"opt-btn-group\">
  4804.                             ";
  4805.             // line 3620
  4806.             $context["idx"] = 0;
  4807.             // line 3621
  4808.             echo "                            ";
  4809.             $context['_parent'] = $context;
  4810.             $context['_seq'] = twig_ensure_traversable((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3621$this->source); })()));
  4811.             foreach ($context['_seq'] as $context["_key"] => $context["pm"]) {
  4812.                 if ($context["pm"]) {
  4813.                     $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3621$this->source); })()) + 1);
  4814.                     // line 3622
  4815.                     echo "                              <label class=\"opt-btn";
  4816.                     if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3622$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3622$this->source); })()), "pm", [], "any"falsefalsefalse3622) == $context["pm"])) || (twig_length_filter($this->env, (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3622$this->source); })())) == 1))) {
  4817.                         echo " is-selected";
  4818.                     }
  4819.                     echo "\"
  4820.                                      onclick=\"mitsumori_simulation_val('pm', '";
  4821.                     // line 3623
  4822.                     echo twig_escape_filter($this->envtwig_escape_filter($this->env$context["pm"], "js"), "html"nulltrue);
  4823.                     echo "');\">
  4824.                                 <input type=\"radio\" name=\"pm\" id=\"pm_";
  4825.                     // line 3624
  4826.                     echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3624$this->source); })()), "html"nulltrue);
  4827.                     echo "\" value=\"";
  4828.                     echo twig_escape_filter($this->env$context["pm"], "html"nulltrue);
  4829.                     echo "\"
  4830.                                        ";
  4831.                     // line 3625
  4832.                     if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3625$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3625$this->source); })()), "pm", [], "any"falsefalsefalse3625) == $context["pm"])) || (twig_length_filter($this->env, (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3625$this->source); })())) == 1))) {
  4833.                         echo "checked";
  4834.                     }
  4835.                     echo ">
  4836.                                 ";
  4837.                     // line 3626
  4838.                     echo twig_escape_filter($this->env$context["pm"], "html"nulltrue);
  4839.                     echo "
  4840.                               </label>
  4841.                             ";
  4842.                 }
  4843.             }
  4844.             $_parent $context['_parent'];
  4845.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pm'], $context['_parent'], $context['loop']);
  4846.             $context array_intersect_key($context$_parent) + $_parent;
  4847.             // line 3629
  4848.             echo "                          </div>
  4849.                         </div>
  4850.                         ";
  4851.         }
  4852.         // line 3632
  4853.         echo "
  4854.                         ";
  4855.         // line 3637
  4856.         echo "                        ";
  4857.         if ((((((((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3637$this->source); })()) && twig_length_filter($this->env, (isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3637$this->source); })()))) && (twig_join_filter((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3637$this->source); })())) != "")) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3637$this->source); })()), "SaleType", [], "any"falsefalsefalse3637), "id", [], "any"falsefalsefalse3637) != 2)) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3637$this->source); })()), "SaleType", [], "any"falsefalsefalse3637), "id", [], "any"falsefalsefalse3637) != 3)) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3637$this->source); })()), "SaleType", [], "any"falsefalsefalse3637), "id", [], "any"falsefalsefalse3637) != 4)) &&  !(isset($context["is_cat43"]) || array_key_exists("is_cat43"$context) ? $context["is_cat43"] : (function () { throw new RuntimeError('Variable "is_cat43" does not exist.'3637$this->source); })()))) {
  4858.             // line 3638
  4859.             echo "                        <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  4860.                           <div class=\"rp-section-label\">";
  4861.             // line 3639
  4862.             echo twig_escape_filter($this->env, (isset($context["option1_label"]) || array_key_exists("option1_label"$context) ? $context["option1_label"] : (function () { throw new RuntimeError('Variable "option1_label" does not exist.'3639$this->source); })()), "html"nulltrue);
  4863.             if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3639$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "option1", [], "any"truetruefalse3639)) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3639$this->source); })()), "option1", [], "any"falsefalsefalse3639))) {
  4864.                 echo ": <span>";
  4865.                 echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3639$this->source); })()), "option1", [], "any"falsefalsefalse3639), "html"nulltrue);
  4866.                 echo "</span>";
  4867.             }
  4868.             echo "</div>
  4869.                           <div class=\"opt-btn-group\">
  4870.                             ";
  4871.             // line 3641
  4872.             $context["idx"] = 0;
  4873.             // line 3642
  4874.             echo "                            ";
  4875.             $context['_parent'] = $context;
  4876.             $context['_seq'] = twig_ensure_traversable((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3642$this->source); })()));
  4877.             foreach ($context['_seq'] as $context["_key"] => $context["opt1"]) {
  4878.                 if ($context["opt1"]) {
  4879.                     $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3642$this->source); })()) + 1);
  4880.                     // line 3643
  4881.                     echo "                              <label class=\"opt-btn";
  4882.                     if (((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3643$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "option1", [], "any"truetruefalse3643)) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3643$this->source); })()), "option1", [], "any"falsefalsefalse3643) == $context["opt1"])) || (twig_length_filter($this->env, (isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3643$this->source); })())) == 1))) {
  4883.                         echo " is-selected";
  4884.                     }
  4885.                     echo "\"
  4886.                                      onclick=\"mitsumori_simulation_val('option1', '";
  4887.                     // line 3644
  4888.                     echo twig_escape_filter($this->envtwig_escape_filter($this->env$context["opt1"], "js"), "html"nulltrue);
  4889.                     echo "');\">
  4890.                                 <input type=\"radio\" name=\"option1\" id=\"option1_";
  4891.                     // line 3645
  4892.                     echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3645$this->source); })()), "html"nulltrue);
  4893.                     echo "\" value=\"";
  4894.                     echo twig_escape_filter($this->env$context["opt1"], "html"nulltrue);
  4895.                     echo "\"
  4896.                                        ";
  4897.                     // line 3646
  4898.                     if (((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3646$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "option1", [], "any"truetruefalse3646)) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3646$this->source); })()), "option1", [], "any"falsefalsefalse3646) == $context["opt1"])) || (twig_length_filter($this->env, (isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3646$this->source); })())) == 1))) {
  4899.                         echo "checked";
  4900.                     }
  4901.                     echo ">
  4902.                                 ";
  4903.                     // line 3647
  4904.                     echo twig_escape_filter($this->env$context["opt1"], "html"nulltrue);
  4905.                     echo "
  4906.                               </label>
  4907.                             ";
  4908.                 }
  4909.             }
  4910.             $_parent $context['_parent'];
  4911.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['opt1'], $context['_parent'], $context['loop']);
  4912.             $context array_intersect_key($context$_parent) + $_parent;
  4913.             // line 3650
  4914.             echo "                          </div>
  4915.                         </div>
  4916.                         ";
  4917.         }
  4918.         // line 3653
  4919.         echo "
  4920.                         ";
  4921.         // line 3655
  4922.         echo "                        ";
  4923.         if (((((((isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'3655$this->source); })()) && twig_length_filter($this->env, (isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'3655$this->source); })()))) && (twig_join_filter((isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'3655$this->source); })())) != "")) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3655$this->source); })()), "SaleType", [], "any"falsefalsefalse3655), "id", [], "any"falsefalsefalse3655) != 2)) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3655$this->source); })()), "SaleType", [], "any"falsefalsefalse3655), "id", [], "any"falsefalsefalse3655) != 3)) &&  !(isset($context["is_cat43"]) || array_key_exists("is_cat43"$context) ? $context["is_cat43"] : (function () { throw new RuntimeError('Variable "is_cat43" does not exist.'3655$this->source); })()))) {
  4924.             // line 3656
  4925.             echo "                        <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  4926.                           <div class=\"rp-section-label\">";
  4927.             // line 3657
  4928.             echo twig_escape_filter($this->env, (isset($context["option2_label"]) || array_key_exists("option2_label"$context) ? $context["option2_label"] : (function () { throw new RuntimeError('Variable "option2_label" does not exist.'3657$this->source); })()), "html"nulltrue);
  4929.             if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3657$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "option2", [], "any"truetruefalse3657)) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3657$this->source); })()), "option2", [], "any"falsefalsefalse3657))) {
  4930.                 echo ": <span>";
  4931.                 echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3657$this->source); })()), "option2", [], "any"falsefalsefalse3657), "html"nulltrue);
  4932.                 echo "</span>";
  4933.             }
  4934.             echo "</div>
  4935.                           <div class=\"opt-btn-group\">
  4936.                             ";
  4937.             // line 3659
  4938.             $context["idx"] = 0;
  4939.             // line 3660
  4940.             echo "                            ";
  4941.             $context['_parent'] = $context;
  4942.             $context['_seq'] = twig_ensure_traversable((isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'3660$this->source); })()));
  4943.             foreach ($context['_seq'] as $context["_key"] => $context["opt2"]) {
  4944.                 if ($context["opt2"]) {
  4945.                     $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3660$this->source); })()) + 1);
  4946.                     // line 3661
  4947.                     echo "                              <label class=\"opt-btn";
  4948.                     if (((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3661$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "option2", [], "any"truetruefalse3661)) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3661$this->source); })()), "option2", [], "any"falsefalsefalse3661) == $context["opt2"])) || (twig_length_filter($this->env, (isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'3661$this->source); })())) == 1))) {
  4949.                         echo " is-selected";
  4950.                     }
  4951.                     echo "\"
  4952.                                      onclick=\"mitsumori_simulation_val('option2', '";
  4953.                     // line 3662
  4954.                     echo twig_escape_filter($this->envtwig_escape_filter($this->env$context["opt2"], "js"), "html"nulltrue);
  4955.                     echo "');\">
  4956.                                 <input type=\"radio\" name=\"option2\" id=\"option2_";
  4957.                     // line 3663
  4958.                     echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3663$this->source); })()), "html"nulltrue);
  4959.                     echo "\" value=\"";
  4960.                     echo twig_escape_filter($this->env$context["opt2"], "html"nulltrue);
  4961.                     echo "\"
  4962.                                        ";
  4963.                     // line 3664
  4964.                     if (((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3664$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "option2", [], "any"truetruefalse3664)) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3664$this->source); })()), "option2", [], "any"falsefalsefalse3664) == $context["opt2"])) || (twig_length_filter($this->env, (isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'3664$this->source); })())) == 1))) {
  4965.                         echo "checked";
  4966.                     }
  4967.                     echo ">
  4968.                                 ";
  4969.                     // line 3665
  4970.                     echo twig_escape_filter($this->env$context["opt2"], "html"nulltrue);
  4971.                     echo "
  4972.                               </label>
  4973.                             ";
  4974.                 }
  4975.             }
  4976.             $_parent $context['_parent'];
  4977.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['opt2'], $context['_parent'], $context['loop']);
  4978.             $context array_intersect_key($context$_parent) + $_parent;
  4979.             // line 3668
  4980.             echo "                          </div>
  4981.                         </div>
  4982.                         ";
  4983.         }
  4984.         // line 3671
  4985.         echo "
  4986. \t\t\t\t\t\t<!-- 1: 施工見積(通常) → 幅/奥行/高さ/素材/カラーは上部の共通ブロックで表示済み -->
  4987. \t\t\t\t\t\t";
  4988.         // line 3673
  4989.         if ((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3673$this->source); })()), "SaleType", [], "any"falsefalsefalse3673), "id", [], "any"falsefalsefalse3673) == 1)) {
  4990.             // line 3674
  4991.             echo "\t\t\t\t\t\t";
  4992.         }
  4993.         // line 3675
  4994.         echo "
  4995. \t\t\t\t\t\t<!-- 2: 施工見積(補助金・窓) 複数タイプ追加対応 (2026-05) -->
  4996. \t\t\t\t\t\t";
  4997.         // line 3677
  4998.         if ((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3677$this->source); })()), "SaleType", [], "any"falsefalsefalse3677), "id", [], "any"falsefalsefalse3677) == 2)) {
  4999.             // line 3678
  5000.             echo "
  5001. \t\t\t\t\t\t\t";
  5002.             // line 3682
  5003.             echo "
  5004. \t\t\t\t\t\t\t";
  5005.             // line 3686
  5006.             echo "\t\t\t\t\t\t\t<style>
  5007. \t\t\t\t\t\t\t\t.ec-productRole__profile {
  5008. \t\t\t\t\t\t\t\t\toverflow: visible !important;
  5009. \t\t\t\t\t\t\t\t\tmax-height: none !important;
  5010. \t\t\t\t\t\t\t\t\theight: auto !important;
  5011. \t\t\t\t\t\t\t\t}
  5012. \t\t\t\t\t\t\t</style>
  5013. \t\t\t\t\t\t\t";
  5014.             // line 3695
  5015.             echo "\t\t\t\t\t\t\t";
  5016.             $context["housing_default"] = _twig_default_filter($this->extensions['Plugin\ProductField\Twig\Extension\EccubeExtension']->getProduct_field(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3695$this->source); })()), "id", [], "any"falsefalsefalse3695), "住宅区分"), "戸建");
  5017.             // line 3696
  5018.             echo "\t\t\t\t\t\t\t<div class=\"card mt-3 mb-3\">
  5019. \t\t\t\t\t\t\t  <div class=\"card-header\" style=\"background:#fff3cd;color:#333;\">
  5020. \t\t\t\t\t\t\t    <strong>お住まいの種別を選択</strong>
  5021. \t\t\t\t\t\t\t    <small class=\"ms-2 text-muted\">補助金単価が変わります</small>
  5022. \t\t\t\t\t\t\t  </div>
  5023. \t\t\t\t\t\t\t  <div class=\"card-body p-2\">
  5024. \t\t\t\t\t\t\t    <div class=\"opt-btn-group\" id=\"window-housing-type-group\">
  5025. \t\t\t\t\t\t\t      <label class=\"opt-btn\">
  5026. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"window_housing_type\" value=\"戸建\"
  5027. \t\t\t\t\t\t\t               ";
  5028.             // line 3705
  5029.             if (((isset($context["housing_default"]) || array_key_exists("housing_default"$context) ? $context["housing_default"] : (function () { throw new RuntimeError('Variable "housing_default" does not exist.'3705$this->source); })()) != "集合住宅")) {
  5030.                 echo "checked";
  5031.             }
  5032.             echo ">
  5033. \t\t\t\t\t\t\t        戸建住宅<small class=\"d-block text-muted\">(延床240㎡以下の非住宅含む)</small>
  5034. \t\t\t\t\t\t\t      </label>
  5035. \t\t\t\t\t\t\t      <label class=\"opt-btn\">
  5036. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"window_housing_type\" value=\"集合住宅\"
  5037. \t\t\t\t\t\t\t               ";
  5038.             // line 3710
  5039.             if (((isset($context["housing_default"]) || array_key_exists("housing_default"$context) ? $context["housing_default"] : (function () { throw new RuntimeError('Variable "housing_default" does not exist.'3710$this->source); })()) == "集合住宅")) {
  5040.                 echo "checked";
  5041.             }
  5042.             echo ">
  5043. \t\t\t\t\t\t\t        集合住宅<small class=\"d-block text-muted\">(低層・中高層/240㎡超の非住宅)</small>
  5044. \t\t\t\t\t\t\t      </label>
  5045. \t\t\t\t\t\t\t    </div>
  5046. \t\t\t\t\t\t\t  </div>
  5047. \t\t\t\t\t\t\t</div>
  5048. \t\t\t\t\t\t\t<div class=\"card mt-3 mb-3\">
  5049. \t\t\t\t\t\t\t  <div class=\"card-header\" style=\"background:#fff3cd;color:#333;\">
  5050. \t\t\t\t\t\t\t    <strong>窓タイプを選択(複数追加可・最大 20)</strong>
  5051. \t\t\t\t\t\t\t  </div>
  5052. \t\t\t\t\t\t\t  <div class=\"card-body p-2\">
  5053. \t\t\t\t\t\t\t    <div id=\"window-types-container\"><!-- 動的に窓タイプブロックが追加される --></div>
  5054. \t\t\t\t\t\t\t    <div class=\"text-center mt-2\">
  5055. \t\t\t\t\t\t\t      <button type=\"button\" id=\"btn-add-window-type\" class=\"btn btn-outline-primary btn-sm\" onclick=\"addWindowType();\">+ 窓タイプを追加</button>
  5056. \t\t\t\t\t\t\t      <div class=\"small text-muted mt-1\">最大 20 タイプまで追加できます</div>
  5057. \t\t\t\t\t\t\t    </div>
  5058. \t\t\t\t\t\t\t  </div>
  5059. \t\t\t\t\t\t\t</div>
  5060. \t\t\t\t\t\t\t";
  5061.             // line 3731
  5062.             echo "\t\t\t\t\t\t\t<template id=\"window-type-template\">
  5063. \t\t\t\t\t\t\t  <div class=\"window-type-block\" data-type-idx=\"__IDX__\" style=\"border:1px solid #ddd;border-radius:6px;padding:10px;margin-bottom:10px;background:#fafafa;\">
  5064. \t\t\t\t\t\t\t    <div class=\"d-flex justify-content-between align-items-center mb-2\">
  5065. \t\t\t\t\t\t\t      <strong>窓タイプ <span class=\"wt-num\">__IDX__</span></strong>
  5066. \t\t\t\t\t\t\t      <button type=\"button\" class=\"btn btn-sm btn-outline-danger btn-remove-window-type\" onclick=\"removeWindowType(this);\">× 削除</button>
  5067. \t\t\t\t\t\t\t    </div>
  5068. \t\t\t\t\t\t\t    ";
  5069.             // line 3739
  5070.             echo "\t\t\t\t\t\t\t    ";
  5071.             if ((((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3739$this->source); })()) && twig_length_filter($this->env, (isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3739$this->source); })()))) && (twig_join_filter((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3739$this->source); })())) != ""))) {
  5072.                 // line 3740
  5073.                 echo "\t\t\t\t\t\t\t    <div class=\"form-group mt-2 pb-2\" style=\"border-bottom:1px dashed rgba(0,0,0,.1)\">
  5074. \t\t\t\t\t\t\t      <div class=\"rp-section-label\">窓タイプ</div>
  5075. \t\t\t\t\t\t\t      <div class=\"opt-btn-group\">
  5076. \t\t\t\t\t\t\t        ";
  5077.                 // line 3743
  5078.                 $context['_parent'] = $context;
  5079.                 $context['_seq'] = twig_ensure_traversable((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3743$this->source); })()));
  5080.                 foreach ($context['_seq'] as $context["_key"] => $context["v"]) {
  5081.                     if ($context["v"]) {
  5082.                         // line 3744
  5083.                         echo "\t\t\t\t\t\t\t          <label class=\"opt-btn\">
  5084. \t\t\t\t\t\t\t            <input type=\"radio\" name=\"wt_subtype___IDX__\" value=\"";
  5085.                         // line 3745
  5086.                         echo twig_escape_filter($this->env$context["v"], "html"nulltrue);
  5087.                         echo "\" data-axis=\"subtype\" onchange=\"onWindowTypeAxisChange(this);\">
  5088. \t\t\t\t\t\t\t            ";
  5089.                         // line 3746
  5090.                         echo twig_escape_filter($this->env$context["v"], "html"nulltrue);
  5091.                         echo "
  5092. \t\t\t\t\t\t\t          </label>
  5093. \t\t\t\t\t\t\t        ";
  5094.                     }
  5095.                 }
  5096.                 $_parent $context['_parent'];
  5097.                 unset($context['_seq'], $context['_iterated'], $context['_key'], $context['v'], $context['_parent'], $context['loop']);
  5098.                 $context array_intersect_key($context$_parent) + $_parent;
  5099.                 // line 3749
  5100.                 echo "\t\t\t\t\t\t\t      </div>
  5101. \t\t\t\t\t\t\t    </div>
  5102. \t\t\t\t\t\t\t    ";
  5103.             }
  5104.             // line 3752
  5105.             echo "
  5106. \t\t\t\t\t\t\t    ";
  5107.             // line 3754
  5108.             echo "\t\t\t\t\t\t\t    ";
  5109.             if ((((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3754$this->source); })()) && twig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3754$this->source); })()))) && (twig_join_filter((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3754$this->source); })())) != ""))) {
  5110.                 // line 3755
  5111.                 echo "\t\t\t\t\t\t\t    <div class=\"form-group mt-2 pb-2\" style=\"border-bottom:1px dashed rgba(0,0,0,.1)\">
  5112. \t\t\t\t\t\t\t      <div class=\"rp-section-label\">幅</div>
  5113. \t\t\t\t\t\t\t      <div class=\"input-group\" style=\"max-width:240px;\">
  5114. \t\t\t\t\t\t\t        <input type=\"number\" name=\"wt_pw___IDX__\" class=\"form-control\" min=\"100\" step=\"10\"
  5115. \t\t\t\t\t\t\t               placeholder=\"例 1750\" data-axis=\"pw\" data-unit=\"mm\"
  5116. \t\t\t\t\t\t\t               oninput=\"onWindowTypeAxisChange(this);\">
  5117. \t\t\t\t\t\t\t        <span class=\"input-group-text\">mm</span>
  5118. \t\t\t\t\t\t\t      </div>
  5119. \t\t\t\t\t\t\t      <small class=\"text-muted\">商品の対応幅: 〜";
  5120.                 // line 3763
  5121.                 echo twig_escape_filter($this->env_twig_default_filter(twig_last($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3763$this->source); })())), ""), "html"nulltrue);
  5122.                 echo "(";
  5123.                 echo twig_escape_filter($this->envtwig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3763$this->source); })())), "html"nulltrue);
  5124.                 echo " 段階の価格帯から自動選択)</small>
  5125. \t\t\t\t\t\t\t    </div>
  5126. \t\t\t\t\t\t\t    ";
  5127.             }
  5128.             // line 3766
  5129.             echo "
  5130. \t\t\t\t\t\t\t    ";
  5131.             // line 3768
  5132.             echo "\t\t\t\t\t\t\t    ";
  5133.             if ((((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3768$this->source); })()) && twig_length_filter($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3768$this->source); })()))) && (twig_join_filter((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3768$this->source); })())) != ""))) {
  5134.                 // line 3769
  5135.                 echo "\t\t\t\t\t\t\t    <div class=\"form-group mt-2 pb-2\" style=\"border-bottom:1px dashed rgba(0,0,0,.1)\">
  5136. \t\t\t\t\t\t\t      <div class=\"rp-section-label\">高さ</div>
  5137. \t\t\t\t\t\t\t      <div class=\"input-group\" style=\"max-width:240px;\">
  5138. \t\t\t\t\t\t\t        <input type=\"number\" name=\"wt_ph___IDX__\" class=\"form-control\" min=\"100\" step=\"10\"
  5139. \t\t\t\t\t\t\t               placeholder=\"例 1200\" data-axis=\"ph\" data-unit=\"mm\"
  5140. \t\t\t\t\t\t\t               oninput=\"onWindowTypeAxisChange(this);\">
  5141. \t\t\t\t\t\t\t        <span class=\"input-group-text\">mm</span>
  5142. \t\t\t\t\t\t\t      </div>
  5143. \t\t\t\t\t\t\t      <small class=\"text-muted\">商品の対応高さ: 〜";
  5144.                 // line 3777
  5145.                 echo twig_escape_filter($this->env_twig_default_filter(twig_last($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3777$this->source); })())), ""), "html"nulltrue);
  5146.                 echo "(";
  5147.                 echo twig_escape_filter($this->envtwig_length_filter($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3777$this->source); })())), "html"nulltrue);
  5148.                 echo " 段階の価格帯から自動選択)</small>
  5149. \t\t\t\t\t\t\t    </div>
  5150. \t\t\t\t\t\t\t    ";
  5151.             }
  5152.             // line 3780
  5153.             echo "
  5154. \t\t\t\t\t\t\t    ";
  5155.             // line 3782
  5156.             echo "\t\t\t\t\t\t\t    ";
  5157.             if ((((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3782$this->source); })()) && twig_length_filter($this->env, (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3782$this->source); })()))) && (twig_join_filter((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3782$this->source); })())) != ""))) {
  5158.                 // line 3783
  5159.                 echo "\t\t\t\t\t\t\t    <div class=\"form-group mt-2 pb-2\" style=\"border-bottom:1px dashed rgba(0,0,0,.1)\">
  5160. \t\t\t\t\t\t\t      <div class=\"rp-section-label\">ガラスタイプ</div>
  5161. \t\t\t\t\t\t\t      <div class=\"opt-btn-group\">
  5162. \t\t\t\t\t\t\t        ";
  5163.                 // line 3786
  5164.                 $context['_parent'] = $context;
  5165.                 $context['_seq'] = twig_ensure_traversable((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3786$this->source); })()));
  5166.                 foreach ($context['_seq'] as $context["_key"] => $context["v"]) {
  5167.                     if ($context["v"]) {
  5168.                         // line 3787
  5169.                         echo "\t\t\t\t\t\t\t          <label class=\"opt-btn\">
  5170. \t\t\t\t\t\t\t            <input type=\"radio\" name=\"wt_pm___IDX__\" value=\"";
  5171.                         // line 3788
  5172.                         echo twig_escape_filter($this->env$context["v"], "html"nulltrue);
  5173.                         echo "\" data-axis=\"pm\" onchange=\"onWindowTypeAxisChange(this);\">
  5174. \t\t\t\t\t\t\t            ";
  5175.                         // line 3789
  5176.                         echo twig_escape_filter($this->env$context["v"], "html"nulltrue);
  5177.                         echo "
  5178. \t\t\t\t\t\t\t          </label>
  5179. \t\t\t\t\t\t\t        ";
  5180.                     }
  5181.                 }
  5182.                 $_parent $context['_parent'];
  5183.                 unset($context['_seq'], $context['_iterated'], $context['_key'], $context['v'], $context['_parent'], $context['loop']);
  5184.                 $context array_intersect_key($context$_parent) + $_parent;
  5185.                 // line 3792
  5186.                 echo "\t\t\t\t\t\t\t      </div>
  5187. \t\t\t\t\t\t\t      <small class=\"text-muted\">「<span style=\"color:#2e7d32;font-weight:bold;\">補助金対象</span>」が付いたガラスは、先進的窓リノベ補助金の対象です。</small>
  5188. \t\t\t\t\t\t\t    </div>
  5189. \t\t\t\t\t\t\t    ";
  5190.             }
  5191.             // line 3796
  5192.             echo "
  5193. \t\t\t\t\t\t\t    ";
  5194.             // line 3798
  5195.             echo "\t\t\t\t\t\t\t    ";
  5196.             if (((isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'3798$this->source); })()) && twig_length_filter($this->env, (isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'3798$this->source); })())))) {
  5197.                 // line 3799
  5198.                 echo "\t\t\t\t\t\t\t    <div class=\"form-group mt-2 pb-2\" style=\"border-bottom:1px dashed rgba(0,0,0,.1)\">
  5199. \t\t\t\t\t\t\t      <div class=\"rp-section-label\">窓枠カラー</div>
  5200. \t\t\t\t\t\t\t      <div class=\"opt-btn-group\">
  5201. \t\t\t\t\t\t\t        ";
  5202.                 // line 3802
  5203.                 $context['_parent'] = $context;
  5204.                 $context['_seq'] = twig_ensure_traversable((isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'3802$this->source); })()));
  5205.                 foreach ($context['_seq'] as $context["_key"] => $context["cc"]) {
  5206.                     if (($context["cc"] && twig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3802))) {
  5207.                         // line 3803
  5208.                         echo "\t\t\t\t\t\t\t          ";
  5209.                         $context["has_img"] = (twig_get_attribute($this->env$this->source$context["cc"], "img", [], "array"truetruefalse3803) &&  !twig_test_empty(twig_get_attribute($this->env$this->source$context["cc"], "img", [], "array"falsefalsefalse3803)));
  5210.                         // line 3804
  5211.                         echo "\t\t\t\t\t\t\t          <label class=\"opt-btn";
  5212.                         if ((isset($context["has_img"]) || array_key_exists("has_img"$context) ? $context["has_img"] : (function () { throw new RuntimeError('Variable "has_img" does not exist.'3804$this->source); })())) {
  5213.                             echo " opt-btn--with-image";
  5214.                         }
  5215.                         echo "\">
  5216. \t\t\t\t\t\t\t            <input type=\"radio\" name=\"wt_pc___IDX__\" value=\"";
  5217.                         // line 3805
  5218.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3805), "html"nulltrue);
  5219.                         echo "\" data-axis=\"pc\" onchange=\"onWindowTypeAxisChange(this);\">
  5220. \t\t\t\t\t\t\t            ";
  5221.                         // line 3806
  5222.                         if ((isset($context["has_img"]) || array_key_exists("has_img"$context) ? $context["has_img"] : (function () { throw new RuntimeError('Variable "has_img" does not exist.'3806$this->source); })())) {
  5223.                             // line 3807
  5224.                             echo "\t\t\t\t\t\t\t              <img src=\"";
  5225.                             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "img", [], "array"falsefalsefalse3807), "html"nulltrue);
  5226.                             echo "\" alt=\"";
  5227.                             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3807), "html"nulltrue);
  5228.                             echo "\" class=\"opt-btn__img\"
  5229. \t\t\t\t\t\t\t                   onerror=\"this.parentNode.classList.remove('opt-btn--with-image'); this.remove();\">
  5230. \t\t\t\t\t\t\t              <span class=\"opt-btn__name\">";
  5231.                             // line 3809
  5232.                             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3809), "html"nulltrue);
  5233.                             echo "</span>
  5234. \t\t\t\t\t\t\t            ";
  5235.                         } else {
  5236.                             // line 3811
  5237.                             echo "\t\t\t\t\t\t\t              ";
  5238.                             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3811), "html"nulltrue);
  5239.                             echo "
  5240. \t\t\t\t\t\t\t            ";
  5241.                         }
  5242.                         // line 3813
  5243.                         echo "\t\t\t\t\t\t\t          </label>
  5244. \t\t\t\t\t\t\t        ";
  5245.                     }
  5246.                 }
  5247.                 $_parent $context['_parent'];
  5248.                 unset($context['_seq'], $context['_iterated'], $context['_key'], $context['cc'], $context['_parent'], $context['loop']);
  5249.                 $context array_intersect_key($context$_parent) + $_parent;
  5250.                 // line 3815
  5251.                 echo "\t\t\t\t\t\t\t      </div>
  5252. \t\t\t\t\t\t\t    </div>
  5253. \t\t\t\t\t\t\t    ";
  5254.             }
  5255.             // line 3818
  5256.             echo "
  5257. \t\t\t\t\t\t\t    ";
  5258.             // line 3820
  5259.             echo "\t\t\t\t\t\t\t    <div class=\"form-group row mt-2 align-items-center\">
  5260. \t\t\t\t\t\t\t      <label class=\"col-4 col-form-label\">セット数</label>
  5261. \t\t\t\t\t\t\t      <div class=\"col-4\">
  5262. \t\t\t\t\t\t\t        <div class=\"input-group\">
  5263. \t\t\t\t\t\t\t          <input type=\"number\" name=\"wt_setqty___IDX__\" class=\"form-control wt-input-setqty\" value=\"1\" min=\"1\" max=\"99\" data-axis=\"setqty\" onchange=\"onWindowTypeAxisChange(this);\">
  5264. \t\t\t\t\t\t\t          <span class=\"input-group-text\">セット</span>
  5265. \t\t\t\t\t\t\t        </div>
  5266. \t\t\t\t\t\t\t      </div>
  5267. \t\t\t\t\t\t\t      <div class=\"col-4 text-end\">
  5268. \t\t\t\t\t\t\t        <small class=\"text-muted\">補助金額<br><span class=\"wt-subsidy-amount\">―</span> 円</small>
  5269. \t\t\t\t\t\t\t      </div>
  5270. \t\t\t\t\t\t\t    </div>
  5271. \t\t\t\t\t\t\t  </div>
  5272. \t\t\t\t\t\t\t</template>
  5273. \t\t\t\t\t\t\t";
  5274.             // line 3836
  5275.             echo "\t\t\t\t\t\t\t<script>
  5276. \t\t\t\t\t\t\t(function() {
  5277. \t\t\t\t\t\t\t\tvar MAX_WINDOW_TYPES = 20;
  5278. \t\t\t\t\t\t\t\tfunction addWindowType() {
  5279. \t\t\t\t\t\t\t\t\tvar container = document.getElementById('window-types-container');
  5280. \t\t\t\t\t\t\t\t\tif (!container) return;
  5281. \t\t\t\t\t\t\t\t\tvar existing = container.querySelectorAll('.window-type-block');
  5282. \t\t\t\t\t\t\t\t\tif (existing.length >= MAX_WINDOW_TYPES) return;
  5283. \t\t\t\t\t\t\t\t\tvar newIdx = existing.length + 1;
  5284. \t\t\t\t\t\t\t\t\tvar tpl = document.getElementById('window-type-template');
  5285. \t\t\t\t\t\t\t\t\tif (!tpl) return;
  5286. \t\t\t\t\t\t\t\t\t// <template> の innerHTML を取り出して __IDX__ を新規連番に置換し、要素化して append.
  5287. \t\t\t\t\t\t\t\t\tvar html = tpl.innerHTML.replace(/__IDX__/g, String(newIdx));
  5288. \t\t\t\t\t\t\t\t\tvar wrapper = document.createElement('div');
  5289. \t\t\t\t\t\t\t\t\twrapper.innerHTML = html.trim();
  5290. \t\t\t\t\t\t\t\t\tvar block = wrapper.firstChild;
  5291. \t\t\t\t\t\t\t\t\tcontainer.appendChild(block);
  5292. \t\t\t\t\t\t\t\t\tdecorateSubsidyGlass(block);
  5293. \t\t\t\t\t\t\t\t\tupdateRemoveButtonVisibility();
  5294. \t\t\t\t\t\t\t\t\tif (typeof recalcAll === 'function') recalcAll();
  5295. \t\t\t\t\t\t\t\t}
  5296. \t\t\t\t\t\t\t\t// 補助金対象ガラスの選択肢に「補助金対象」バッジ + 緑枠を付与する.
  5297. \t\t\t\t\t\t\t\t// 判定は calc script 側の window.glassYieldsSubsidy に委譲 (ロジック二重化を避ける)。
  5298. \t\t\t\t\t\t\t\tfunction decorateSubsidyGlass(block) {
  5299. \t\t\t\t\t\t\t\t\tif (!block || typeof window.glassYieldsSubsidy !== 'function') return;
  5300. \t\t\t\t\t\t\t\t\tvar radios = block.querySelectorAll('input[data-axis=\"pm\"]');
  5301. \t\t\t\t\t\t\t\t\tradios.forEach(function(inp) {
  5302. \t\t\t\t\t\t\t\t\t\tvar label = inp.closest('.opt-btn');
  5303. \t\t\t\t\t\t\t\t\t\tif (!label || label.querySelector('.opt-btn__subsidy-badge')) return;
  5304. \t\t\t\t\t\t\t\t\t\tif (window.glassYieldsSubsidy(inp.value)) {
  5305. \t\t\t\t\t\t\t\t\t\t\tlabel.classList.add('opt-btn--subsidy');
  5306. \t\t\t\t\t\t\t\t\t\t\tvar badge = document.createElement('span');
  5307. \t\t\t\t\t\t\t\t\t\t\tbadge.className = 'opt-btn__subsidy-badge';
  5308. \t\t\t\t\t\t\t\t\t\t\tbadge.textContent = '補助金対象';
  5309. \t\t\t\t\t\t\t\t\t\t\tlabel.appendChild(badge);
  5310. \t\t\t\t\t\t\t\t\t\t}
  5311. \t\t\t\t\t\t\t\t\t});
  5312. \t\t\t\t\t\t\t\t}
  5313. \t\t\t\t\t\t\t\tfunction removeWindowType(btn) {
  5314. \t\t\t\t\t\t\t\t\tvar block = btn.closest('.window-type-block');
  5315. \t\t\t\t\t\t\t\t\tif (!block) return;
  5316. \t\t\t\t\t\t\t\t\tblock.remove();
  5317. \t\t\t\t\t\t\t\t\treindexBlocks();
  5318. \t\t\t\t\t\t\t\t\tupdateRemoveButtonVisibility();
  5319. \t\t\t\t\t\t\t\t\tif (typeof recalcAll === 'function') recalcAll();
  5320. \t\t\t\t\t\t\t\t}
  5321. \t\t\t\t\t\t\t\tfunction updateRemoveButtonVisibility() {
  5322. \t\t\t\t\t\t\t\t\tvar blocks = document.querySelectorAll('#window-types-container .window-type-block');
  5323. \t\t\t\t\t\t\t\t\tblocks.forEach(function(b) {
  5324. \t\t\t\t\t\t\t\t\t\tvar btn = b.querySelector('.btn-remove-window-type');
  5325. \t\t\t\t\t\t\t\t\t\tif (btn) btn.style.display = blocks.length > 1 ? '' : 'none';
  5326. \t\t\t\t\t\t\t\t\t});
  5327. \t\t\t\t\t\t\t\t}
  5328. \t\t\t\t\t\t\t\tfunction reindexBlocks() {
  5329. \t\t\t\t\t\t\t\t\t// ブロック削除後に 1 から振り直し. input[name] の末尾 _N も書き換える.
  5330. \t\t\t\t\t\t\t\t\tvar blocks = document.querySelectorAll('#window-types-container .window-type-block');
  5331. \t\t\t\t\t\t\t\t\tblocks.forEach(function(b, i) {
  5332. \t\t\t\t\t\t\t\t\t\tvar n = i + 1;
  5333. \t\t\t\t\t\t\t\t\t\tb.setAttribute('data-type-idx', String(n));
  5334. \t\t\t\t\t\t\t\t\t\tvar numSpan = b.querySelector('.wt-num');
  5335. \t\t\t\t\t\t\t\t\t\tif (numSpan) numSpan.textContent = String(n);
  5336. \t\t\t\t\t\t\t\t\t\tb.querySelectorAll('input[name]').forEach(function(inp) {
  5337. \t\t\t\t\t\t\t\t\t\t\tinp.name = inp.name.replace(/_\\d+\$/, '_' + n);
  5338. \t\t\t\t\t\t\t\t\t\t});
  5339. \t\t\t\t\t\t\t\t\t});
  5340. \t\t\t\t\t\t\t\t}
  5341. \t\t\t\t\t\t\t\t// 軸変更イベント. recalcAll が定義されていれば再計算 (task 2 で実装).
  5342. \t\t\t\t\t\t\t\twindow.onWindowTypeAxisChange = function() {
  5343. \t\t\t\t\t\t\t\t\tif (typeof recalcAll === 'function') recalcAll();
  5344. \t\t\t\t\t\t\t\t};
  5345. \t\t\t\t\t\t\t\twindow.addWindowType = addWindowType;
  5346. \t\t\t\t\t\t\t\twindow.removeWindowType = removeWindowType;
  5347. \t\t\t\t\t\t\t\t// 隠し radio(opacity:0/pointer-events:none) を label で包む opt-btn は iOS で初回タップの
  5348. \t\t\t\t\t\t\t\t// change が不発になりやすい。窓タイプ/住宅区分は label に onclick が無く change 依存だった
  5349. \t\t\t\t\t\t\t\t// ため「2回タッチ/選択できない」が発生。click は確実に発火するので委譲 click で選択状態・
  5350. \t\t\t\t\t\t\t\t// is-selected・再計算を行う(JSで複製される窓タイプにも委譲で対応)。
  5351. \t\t\t\t\t\t\t\tdocument.addEventListener('click', function(ev) {
  5352. \t\t\t\t\t\t\t\t\tif (!ev.target || !ev.target.closest) return;
  5353. \t\t\t\t\t\t\t\t\tvar label = ev.target.closest('.opt-btn');
  5354. \t\t\t\t\t\t\t\t\tif (!label) return;
  5355. \t\t\t\t\t\t\t\t\tif (!label.closest('#window-types-container') && !label.closest('#window-housing-type-group')) return;
  5356. \t\t\t\t\t\t\t\t\tvar input = label.querySelector('input[type=\"radio\"]');
  5357. \t\t\t\t\t\t\t\t\tif (!input || input.disabled) return;
  5358. \t\t\t\t\t\t\t\t\tinput.checked = true;
  5359. \t\t\t\t\t\t\t\t\tvar nm = input.getAttribute('name');
  5360. \t\t\t\t\t\t\t\t\tif (nm) {
  5361. \t\t\t\t\t\t\t\t\t\tdocument.querySelectorAll('input[name=\"' + nm + '\"]').forEach(function(i) {
  5362. \t\t\t\t\t\t\t\t\t\t\tvar l = i.closest('.opt-btn');
  5363. \t\t\t\t\t\t\t\t\t\t\tif (l) l.classList.toggle('is-selected', i.checked);
  5364. \t\t\t\t\t\t\t\t\t\t});
  5365. \t\t\t\t\t\t\t\t\t}
  5366. \t\t\t\t\t\t\t\t\tif (typeof recalcAll === 'function') recalcAll();
  5367. \t\t\t\t\t\t\t\t});
  5368. \t\t\t\t\t\t\t\t// 初期表示で 1 ブロック追加 + 住宅区分ラジオの change で再計算.
  5369. \t\t\t\t\t\t\t\tdocument.addEventListener('DOMContentLoaded', function() {
  5370. \t\t\t\t\t\t\t\t\tif (document.querySelector('#window-types-container')) {
  5371. \t\t\t\t\t\t\t\t\t\taddWindowType();
  5372. \t\t\t\t\t\t\t\t\t}
  5373. \t\t\t\t\t\t\t\t\tvar housingInputs = document.querySelectorAll('input[name=\"window_housing_type\"]');
  5374. \t\t\t\t\t\t\t\t\tvar syncHousingSelectedClass = function() {
  5375. \t\t\t\t\t\t\t\t\t\thousingInputs.forEach(function(el) {
  5376. \t\t\t\t\t\t\t\t\t\t\tvar lbl = el.closest('.opt-btn');
  5377. \t\t\t\t\t\t\t\t\t\t\tif (!lbl) return;
  5378. \t\t\t\t\t\t\t\t\t\t\tif (el.checked) lbl.classList.add('is-selected');
  5379. \t\t\t\t\t\t\t\t\t\t\telse            lbl.classList.remove('is-selected');
  5380. \t\t\t\t\t\t\t\t\t\t});
  5381. \t\t\t\t\t\t\t\t\t};
  5382. \t\t\t\t\t\t\t\t\tsyncHousingSelectedClass();
  5383. \t\t\t\t\t\t\t\t\thousingInputs.forEach(function(el) {
  5384. \t\t\t\t\t\t\t\t\t\tel.addEventListener('change', function() {
  5385. \t\t\t\t\t\t\t\t\t\t\tsyncHousingSelectedClass();
  5386. \t\t\t\t\t\t\t\t\t\t\tif (typeof recalcAll === 'function') recalcAll();
  5387. \t\t\t\t\t\t\t\t\t\t});
  5388. \t\t\t\t\t\t\t\t\t});
  5389. \t\t\t\t\t\t\t\t});
  5390. \t\t\t\t\t\t\t})();
  5391. \t\t\t\t\t\t\t</script>
  5392. \t\t\t\t\t\t";
  5393.         }
  5394.         // line 3964
  5395.         echo "
  5396. \t\t\t\t\t\t<!-- 3: 施工見積(物置・ゴミステーション) -->
  5397. \t\t\t\t\t\t";
  5398.         // line 3966
  5399.         if ((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3966$this->source); })()), "SaleType", [], "any"falsefalsefalse3966), "id", [], "any"falsefalsefalse3966) == 3)) {
  5400.             // line 3967
  5401.             echo "
  5402. \t\t\t\t\t\t\t";
  5403.             // line 3969
  5404.             echo "\t\t\t\t\t\t\t";
  5405.             if ((((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3969$this->source); })()) && twig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3969$this->source); })()))) && (twig_join_filter((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3969$this->source); })())) != ""))) {
  5406.                 // line 3970
  5407.                 echo "\t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  5408. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">幅";
  5409.                 // line 3971
  5410.                 if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3971$this->source); })()) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3971$this->source); })()), "pw", [], "any"falsefalsefalse3971))) {
  5411.                     echo ": <span>";
  5412.                     echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3971$this->source); })()), "pw", [], "any"falsefalsefalse3971), "html"nulltrue);
  5413.                     echo "</span>";
  5414.                 }
  5415.                 echo "</div>
  5416. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  5417. \t\t\t\t\t\t\t    ";
  5418.                 // line 3973
  5419.                 $context["idx"] = 0;
  5420.                 // line 3974
  5421.                 echo "\t\t\t\t\t\t\t    ";
  5422.                 $context['_parent'] = $context;
  5423.                 $context['_seq'] = twig_ensure_traversable((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3974$this->source); })()));
  5424.                 foreach ($context['_seq'] as $context["_key"] => $context["pw_val"]) {
  5425.                     if ($context["pw_val"]) {
  5426.                         $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3974$this->source); })()) + 1);
  5427.                         // line 3975
  5428.                         echo "\t\t\t\t\t\t\t      <label class=\"opt-btn";
  5429.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3975$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3975$this->source); })()), "pw", [], "any"falsefalsefalse3975) == $context["pw_val"])) || (twig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3975$this->source); })())) == 1))) {
  5430.                             echo " is-selected";
  5431.                         }
  5432.                         echo "\"
  5433. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('pw','pw3_";
  5434.                         // line 3976
  5435.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3976$this->source); })()), "html"nulltrue);
  5436.                         echo "');\">
  5437. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"pw\" id=\"pw3_";
  5438.                         // line 3977
  5439.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3977$this->source); })()), "html"nulltrue);
  5440.                         echo "\" value=\"";
  5441.                         echo twig_escape_filter($this->env$context["pw_val"], "html"nulltrue);
  5442.                         echo "\"
  5443. \t\t\t\t\t\t\t               ";
  5444.                         // line 3978
  5445.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3978$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3978$this->source); })()), "pw", [], "any"falsefalsefalse3978) == $context["pw_val"])) || (twig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3978$this->source); })())) == 1))) {
  5446.                             echo "checked";
  5447.                         }
  5448.                         echo ">
  5449. \t\t\t\t\t\t\t        ";
  5450.                         // line 3979
  5451.                         echo twig_escape_filter($this->env$context["pw_val"], "html"nulltrue);
  5452.                         echo "
  5453. \t\t\t\t\t\t\t      </label>
  5454. \t\t\t\t\t\t\t    ";
  5455.                     }
  5456.                 }
  5457.                 $_parent $context['_parent'];
  5458.                 unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pw_val'], $context['_parent'], $context['loop']);
  5459.                 $context array_intersect_key($context$_parent) + $_parent;
  5460.                 // line 3982
  5461.                 echo "\t\t\t\t\t\t\t  </div>
  5462. \t\t\t\t\t\t\t</div>
  5463. \t\t\t\t\t\t\t";
  5464.             }
  5465.             // line 3985
  5466.             echo "
  5467. \t\t\t\t\t\t\t";
  5468.             // line 3986
  5469.             if ((((isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3986$this->source); })()) && twig_length_filter($this->env, (isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3986$this->source); })()))) && (twig_join_filter((isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3986$this->source); })())) != ""))) {
  5470.                 // line 3987
  5471.                 echo "\t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  5472. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">奥行き";
  5473.                 // line 3988
  5474.                 if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3988$this->source); })()) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3988$this->source); })()), "pd", [], "any"falsefalsefalse3988))) {
  5475.                     echo ": <span>";
  5476.                     echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3988$this->source); })()), "pd", [], "any"falsefalsefalse3988), "html"nulltrue);
  5477.                     echo "</span>";
  5478.                 }
  5479.                 echo "</div>
  5480. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  5481. \t\t\t\t\t\t\t    ";
  5482.                 // line 3990
  5483.                 $context["idx"] = 0;
  5484.                 // line 3991
  5485.                 echo "\t\t\t\t\t\t\t    ";
  5486.                 $context['_parent'] = $context;
  5487.                 $context['_seq'] = twig_ensure_traversable((isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3991$this->source); })()));
  5488.                 foreach ($context['_seq'] as $context["_key"] => $context["pd_val"]) {
  5489.                     if ($context["pd_val"]) {
  5490.                         $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3991$this->source); })()) + 1);
  5491.                         // line 3992
  5492.                         echo "\t\t\t\t\t\t\t      <label class=\"opt-btn";
  5493.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3992$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3992$this->source); })()), "pd", [], "any"falsefalsefalse3992) == $context["pd_val"])) || (twig_length_filter($this->env, (isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3992$this->source); })())) == 1))) {
  5494.                             echo " is-selected";
  5495.                         }
  5496.                         echo "\"
  5497. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('pd','pd3_";
  5498.                         // line 3993
  5499.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3993$this->source); })()), "html"nulltrue);
  5500.                         echo "');\">
  5501. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"pd\" id=\"pd3_";
  5502.                         // line 3994
  5503.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3994$this->source); })()), "html"nulltrue);
  5504.                         echo "\" value=\"";
  5505.                         echo twig_escape_filter($this->env$context["pd_val"], "html"nulltrue);
  5506.                         echo "\"
  5507. \t\t\t\t\t\t\t               ";
  5508.                         // line 3995
  5509.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3995$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3995$this->source); })()), "pd", [], "any"falsefalsefalse3995) == $context["pd_val"])) || (twig_length_filter($this->env, (isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3995$this->source); })())) == 1))) {
  5510.                             echo "checked";
  5511.                         }
  5512.                         echo ">
  5513. \t\t\t\t\t\t\t        ";
  5514.                         // line 3996
  5515.                         echo twig_escape_filter($this->env$context["pd_val"], "html"nulltrue);
  5516.                         echo "
  5517. \t\t\t\t\t\t\t      </label>
  5518. \t\t\t\t\t\t\t    ";
  5519.                     }
  5520.                 }
  5521.                 $_parent $context['_parent'];
  5522.                 unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pd_val'], $context['_parent'], $context['loop']);
  5523.                 $context array_intersect_key($context$_parent) + $_parent;
  5524.                 // line 3999
  5525.                 echo "\t\t\t\t\t\t\t  </div>
  5526. \t\t\t\t\t\t\t</div>
  5527. \t\t\t\t\t\t\t";
  5528.             }
  5529.             // line 4002
  5530.             echo "
  5531. \t\t\t\t\t\t\t";
  5532.             // line 4003
  5533.             if ((((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'4003$this->source); })()) && twig_length_filter($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'4003$this->source); })()))) && (twig_join_filter((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'4003$this->source); })())) != ""))) {
  5534.                 // line 4004
  5535.                 echo "\t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  5536. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">高さ";
  5537.                 // line 4005
  5538.                 if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4005$this->source); })()) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4005$this->source); })()), "ph", [], "any"falsefalsefalse4005))) {
  5539.                     echo ": <span>";
  5540.                     echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4005$this->source); })()), "ph", [], "any"falsefalsefalse4005), "html"nulltrue);
  5541.                     echo "</span>";
  5542.                 }
  5543.                 echo "</div>
  5544. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  5545. \t\t\t\t\t\t\t    ";
  5546.                 // line 4007
  5547.                 $context["idx"] = 0;
  5548.                 // line 4008
  5549.                 echo "\t\t\t\t\t\t\t    ";
  5550.                 $context['_parent'] = $context;
  5551.                 $context['_seq'] = twig_ensure_traversable((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'4008$this->source); })()));
  5552.                 foreach ($context['_seq'] as $context["_key"] => $context["ph_val"]) {
  5553.                     if ($context["ph_val"]) {
  5554.                         $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4008$this->source); })()) + 1);
  5555.                         // line 4009
  5556.                         echo "\t\t\t\t\t\t\t      <label class=\"opt-btn";
  5557.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4009$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4009$this->source); })()), "ph", [], "any"falsefalsefalse4009) == $context["ph_val"])) || (twig_length_filter($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'4009$this->source); })())) == 1))) {
  5558.                             echo " is-selected";
  5559.                         }
  5560.                         echo "\"
  5561. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('ph','ph3_";
  5562.                         // line 4010
  5563.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4010$this->source); })()), "html"nulltrue);
  5564.                         echo "');\">
  5565. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"ph\" id=\"ph3_";
  5566.                         // line 4011
  5567.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4011$this->source); })()), "html"nulltrue);
  5568.                         echo "\" value=\"";
  5569.                         echo twig_escape_filter($this->env$context["ph_val"], "html"nulltrue);
  5570.                         echo "\"
  5571. \t\t\t\t\t\t\t               ";
  5572.                         // line 4012
  5573.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4012$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4012$this->source); })()), "ph", [], "any"falsefalsefalse4012) == $context["ph_val"])) || (twig_length_filter($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'4012$this->source); })())) == 1))) {
  5574.                             echo "checked";
  5575.                         }
  5576.                         echo ">
  5577. \t\t\t\t\t\t\t        ";
  5578.                         // line 4013
  5579.                         echo twig_escape_filter($this->env$context["ph_val"], "html"nulltrue);
  5580.                         echo "
  5581. \t\t\t\t\t\t\t      </label>
  5582. \t\t\t\t\t\t\t    ";
  5583.                     }
  5584.                 }
  5585.                 $_parent $context['_parent'];
  5586.                 unset($context['_seq'], $context['_iterated'], $context['_key'], $context['ph_val'], $context['_parent'], $context['loop']);
  5587.                 $context array_intersect_key($context$_parent) + $_parent;
  5588.                 // line 4016
  5589.                 echo "\t\t\t\t\t\t\t  </div>
  5590. \t\t\t\t\t\t\t</div>
  5591. \t\t\t\t\t\t\t";
  5592.             }
  5593.             // line 4019
  5594.             echo "
  5595. \t\t\t\t\t\t\t";
  5596.             // line 4021
  5597.             echo "\t\t\t\t\t\t\t";
  5598.             if ((((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'4021$this->source); })()) && twig_length_filter($this->env, (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'4021$this->source); })()))) && (twig_join_filter((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'4021$this->source); })())) != ""))) {
  5599.                 // line 4022
  5600.                 echo "\t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  5601. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">棚タイプ <small class=\"text-muted\">(間仕切り仕様)</small>";
  5602.                 // line 4023
  5603.                 if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4023$this->source); })()) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4023$this->source); })()), "pm", [], "any"falsefalsefalse4023))) {
  5604.                     echo ": <span>";
  5605.                     echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4023$this->source); })()), "pm", [], "any"falsefalsefalse4023), "html"nulltrue);
  5606.                     echo "</span>";
  5607.                 }
  5608.                 echo "</div>
  5609. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  5610. \t\t\t\t\t\t\t    ";
  5611.                 // line 4025
  5612.                 $context["idx"] = 0;
  5613.                 // line 4026
  5614.                 echo "\t\t\t\t\t\t\t    ";
  5615.                 $context['_parent'] = $context;
  5616.                 $context['_seq'] = twig_ensure_traversable((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'4026$this->source); })()));
  5617.                 foreach ($context['_seq'] as $context["_key"] => $context["pm_val"]) {
  5618.                     if ($context["pm_val"]) {
  5619.                         $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4026$this->source); })()) + 1);
  5620.                         // line 4027
  5621.                         echo "\t\t\t\t\t\t\t      <label class=\"opt-btn";
  5622.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4027$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4027$this->source); })()), "pm", [], "any"falsefalsefalse4027) == $context["pm_val"])) || (twig_length_filter($this->env, (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'4027$this->source); })())) == 1))) {
  5623.                             echo " is-selected";
  5624.                         }
  5625.                         echo "\"
  5626. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('pm','pm3_";
  5627.                         // line 4028
  5628.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4028$this->source); })()), "html"nulltrue);
  5629.                         echo "');\">
  5630. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"pm\" id=\"pm3_";
  5631.                         // line 4029
  5632.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4029$this->source); })()), "html"nulltrue);
  5633.                         echo "\" value=\"";
  5634.                         echo twig_escape_filter($this->env$context["pm_val"], "html"nulltrue);
  5635.                         echo "\"
  5636. \t\t\t\t\t\t\t               ";
  5637.                         // line 4030
  5638.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4030$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4030$this->source); })()), "pm", [], "any"falsefalsefalse4030) == $context["pm_val"])) || (twig_length_filter($this->env, (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'4030$this->source); })())) == 1))) {
  5639.                             echo "checked";
  5640.                         }
  5641.                         echo ">
  5642. \t\t\t\t\t\t\t        ";
  5643.                         // line 4031
  5644.                         echo twig_escape_filter($this->env$context["pm_val"], "html"nulltrue);
  5645.                         echo "
  5646. \t\t\t\t\t\t\t      </label>
  5647. \t\t\t\t\t\t\t    ";
  5648.                     }
  5649.                 }
  5650.                 $_parent $context['_parent'];
  5651.                 unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pm_val'], $context['_parent'], $context['loop']);
  5652.                 $context array_intersect_key($context$_parent) + $_parent;
  5653.                 // line 4034
  5654.                 echo "\t\t\t\t\t\t\t  </div>
  5655. \t\t\t\t\t\t\t</div>
  5656. \t\t\t\t\t\t\t";
  5657.             }
  5658.             // line 4037
  5659.             echo "
  5660. \t\t\t\t\t\t\t";
  5661.             // line 4039
  5662.             echo "\t\t\t\t\t\t\t";
  5663.             if ((((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'4039$this->source); })()) && twig_length_filter($this->env, (isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'4039$this->source); })()))) && (twig_join_filter((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'4039$this->source); })())) != ""))) {
  5664.                 // line 4040
  5665.                 echo "\t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  5666. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">";
  5667.                 // line 4041
  5668.                 echo twig_escape_filter($this->env, (isset($context["option1_label"]) || array_key_exists("option1_label"$context) ? $context["option1_label"] : (function () { throw new RuntimeError('Variable "option1_label" does not exist.'4041$this->source); })()), "html"nulltrue);
  5669.                 if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4041$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "option1", [], "any"truetruefalse4041)) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4041$this->source); })()), "option1", [], "any"falsefalsefalse4041))) {
  5670.                     echo ": <span>";
  5671.                     echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4041$this->source); })()), "option1", [], "any"falsefalsefalse4041), "html"nulltrue);
  5672.                     echo "</span>";
  5673.                 }
  5674.                 echo "</div>
  5675. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  5676. \t\t\t\t\t\t\t    ";
  5677.                 // line 4043
  5678.                 $context["idx"] = 0;
  5679.                 // line 4044
  5680.                 echo "\t\t\t\t\t\t\t    ";
  5681.                 $context['_parent'] = $context;
  5682.                 $context['_seq'] = twig_ensure_traversable((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'4044$this->source); })()));
  5683.                 foreach ($context['_seq'] as $context["_key"] => $context["opt1_val"]) {
  5684.                     if ($context["opt1_val"]) {
  5685.                         $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4044$this->source); })()) + 1);
  5686.                         // line 4045
  5687.                         echo "\t\t\t\t\t\t\t      <label class=\"opt-btn";
  5688.                         if (((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4045$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "option1", [], "any"truetruefalse4045)) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4045$this->source); })()), "option1", [], "any"falsefalsefalse4045) == $context["opt1_val"])) || (twig_length_filter($this->env, (isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'4045$this->source); })())) == 1))) {
  5689.                             echo " is-selected";
  5690.                         }
  5691.                         echo "\"
  5692. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('option1','option1_3_";
  5693.                         // line 4046
  5694.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4046$this->source); })()), "html"nulltrue);
  5695.                         echo "');\">
  5696. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"option1\" id=\"option1_3_";
  5697.                         // line 4047
  5698.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4047$this->source); })()), "html"nulltrue);
  5699.                         echo "\" value=\"";
  5700.                         echo twig_escape_filter($this->env$context["opt1_val"], "html"nulltrue);
  5701.                         echo "\"
  5702. \t\t\t\t\t\t\t               ";
  5703.                         // line 4048
  5704.                         if (((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4048$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "option1", [], "any"truetruefalse4048)) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4048$this->source); })()), "option1", [], "any"falsefalsefalse4048) == $context["opt1_val"])) || (twig_length_filter($this->env, (isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'4048$this->source); })())) == 1))) {
  5705.                             echo "checked";
  5706.                         }
  5707.                         echo ">
  5708. \t\t\t\t\t\t\t        ";
  5709.                         // line 4049
  5710.                         echo twig_escape_filter($this->env$context["opt1_val"], "html"nulltrue);
  5711.                         echo "
  5712. \t\t\t\t\t\t\t      </label>
  5713. \t\t\t\t\t\t\t    ";
  5714.                     }
  5715.                 }
  5716.                 $_parent $context['_parent'];
  5717.                 unset($context['_seq'], $context['_iterated'], $context['_key'], $context['opt1_val'], $context['_parent'], $context['loop']);
  5718.                 $context array_intersect_key($context$_parent) + $_parent;
  5719.                 // line 4052
  5720.                 echo "\t\t\t\t\t\t\t  </div>
  5721. \t\t\t\t\t\t\t</div>
  5722. \t\t\t\t\t\t\t";
  5723.             }
  5724.             // line 4055
  5725.             echo "
  5726. \t\t\t\t\t\t\t";
  5727.             // line 4057
  5728.             echo "\t\t\t\t\t\t\t";
  5729.             if (((isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'4057$this->source); })()) && twig_length_filter($this->env, (isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'4057$this->source); })())))) {
  5730.                 // line 4058
  5731.                 echo "\t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  5732. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">カラー";
  5733.                 // line 4059
  5734.                 if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4059$this->source); })()) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4059$this->source); })()), "pc", [], "any"falsefalsefalse4059))) {
  5735.                     echo ": <span>";
  5736.                     echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4059$this->source); })()), "pc", [], "any"falsefalsefalse4059), "html"nulltrue);
  5737.                     echo "</span>";
  5738.                 }
  5739.                 echo "</div>
  5740. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  5741. \t\t\t\t\t\t\t    ";
  5742.                 // line 4061
  5743.                 $context["idx"] = 0;
  5744.                 // line 4062
  5745.                 echo "\t\t\t\t\t\t\t    ";
  5746.                 $context['_parent'] = $context;
  5747.                 $context['_seq'] = twig_ensure_traversable((isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'4062$this->source); })()));
  5748.                 foreach ($context['_seq'] as $context["_key"] => $context["cc"]) {
  5749.                     if (($context["cc"] && twig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse4062))) {
  5750.                         $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4062$this->source); })()) + 1);
  5751.                         // line 4063
  5752.                         echo "\t\t\t\t\t\t\t      <label class=\"opt-btn";
  5753.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4063$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4063$this->source); })()), "pc", [], "any"falsefalsefalse4063) == twig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse4063))) || (twig_length_filter($this->env, (isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'4063$this->source); })())) == 1))) {
  5754.                             echo " is-selected";
  5755.                         }
  5756.                         echo "\"
  5757. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('pc','cc3_";
  5758.                         // line 4064
  5759.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4064$this->source); })()), "html"nulltrue);
  5760.                         echo "');\">
  5761. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"color3\" id=\"cc3_";
  5762.                         // line 4065
  5763.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4065$this->source); })()), "html"nulltrue);
  5764.                         echo "\" value=\"";
  5765.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse4065), "html"nulltrue);
  5766.                         echo "\"
  5767. \t\t\t\t\t\t\t               ";
  5768.                         // line 4066
  5769.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4066$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4066$this->source); })()), "pc", [], "any"falsefalsefalse4066) == twig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse4066))) || (twig_length_filter($this->env, (isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'4066$this->source); })())) == 1))) {
  5770.                             echo "checked";
  5771.                         }
  5772.                         echo ">
  5773. \t\t\t\t\t\t\t        ";
  5774.                         // line 4067
  5775.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse4067), "html"nulltrue);
  5776.                         echo "
  5777. \t\t\t\t\t\t\t      </label>
  5778. \t\t\t\t\t\t\t    ";
  5779.                     }
  5780.                 }
  5781.                 $_parent $context['_parent'];
  5782.                 unset($context['_seq'], $context['_iterated'], $context['_key'], $context['cc'], $context['_parent'], $context['loop']);
  5783.                 $context array_intersect_key($context$_parent) + $_parent;
  5784.                 // line 4070
  5785.                 echo "\t\t\t\t\t\t\t  </div>
  5786. \t\t\t\t\t\t\t</div>
  5787. \t\t\t\t\t\t\t";
  5788.             }
  5789.             // line 4073
  5790.             echo "
  5791. \t\t\t\t\t\t\t";
  5792.             // line 4075
  5793.             echo "\t\t\t\t\t\t\t<div class=\"form-group row mt-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  5794. \t\t\t\t\t\t\t  <label class=\"col-4 col-form-label\">台数</label>
  5795. \t\t\t\t\t\t\t  <div class=\"col-4\">
  5796. \t\t\t\t\t\t\t    <div class=\"input-group mb-3\">
  5797. \t\t\t\t\t\t\t      <input type=\"number\" name=\"daisu\" id=\"daisu\" class=\"form-control\" value=\"";
  5798.             // line 4079
  5799.             echo twig_escape_filter($this->env, ((twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "daisu", [], "any"truetruefalse4079)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "daisu", [], "any"falsefalsefalse4079), "1")) : ("1")), "html"nulltrue);
  5800.             echo "\" min=\"1\" max=\"10\" onchange=\"mitsumori_simulation('daisu','daisu');\">
  5801. \t\t\t\t\t\t\t      <span class=\"input-group-text\">台</span>
  5802. \t\t\t\t\t\t\t    </div>
  5803. \t\t\t\t\t\t\t  </div>
  5804. \t\t\t\t\t\t\t  <div class=\"col-4\">
  5805. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-info\" onclick=\"daisu(+1);\">+</button>
  5806. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-danger\" onclick=\"daisu(-1);\">ー</button>
  5807. \t\t\t\t\t\t\t  </div>
  5808. \t\t\t\t\t\t\t</div>
  5809. \t\t\t\t\t\t";
  5810.         }
  5811.         // line 4090
  5812.         echo "
  5813. \t\t\t\t\t\t<!-- 4: 施工見積(フェンス・組み立て式) -->
  5814. \t\t\t\t\t\t";
  5815.         // line 4092
  5816.         if ((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'4092$this->source); })()), "SaleType", [], "any"falsefalsefalse4092), "id", [], "any"falsefalsefalse4092) == 4)) {
  5817.             // line 4093
  5818.             echo "
  5819. \t\t\t\t\t\t\t";
  5820.             // line 4095
  5821.             echo "\t\t\t\t\t\t\t<div class=\"form-group row mt-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  5822. \t\t\t\t\t\t\t  <label class=\"col-4 col-form-label\">枚数</label>
  5823. \t\t\t\t\t\t\t  <div class=\"col-4 mb-3\">
  5824. \t\t\t\t\t\t\t    <div class=\"input-group\">
  5825. \t\t\t\t\t\t\t      <input type=\"number\" name=\"maisu\" id=\"maisu\" class=\"form-control\" value=\"";
  5826.             // line 4099
  5827.             echo twig_escape_filter($this->env, ((twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "maisu", [], "any"truetruefalse4099)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "maisu", [], "any"falsefalsefalse4099), "3")) : ("3")), "html"nulltrue);
  5828.             echo "\" min=\"3\" max=\"20\" onchange=\"if(parseInt(this.value)<3)this.value=3; mitsumori_simulation('maisu','maisu');\">
  5829. \t\t\t\t\t\t\t      <span class=\"input-group-text\">枚</span>
  5830. \t\t\t\t\t\t\t    </div>
  5831. \t\t\t\t\t\t\t  </div>
  5832. \t\t\t\t\t\t\t  <div class=\"col-4\">
  5833. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-info\" onclick=\"maisu(+1);\">+</button>
  5834. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-danger\" onclick=\"maisu(-1);\">ー</button>
  5835. \t\t\t\t\t\t\t  </div>
  5836. \t\t\t\t\t\t\t</div>
  5837. \t\t\t\t\t\t";
  5838.         }
  5839.         // line 4110
  5840.         echo "
  5841. \t\t\t\t\t\t<!-- 5: 施工見積(ウッドデッキ・タイルデッキ) -->
  5842. \t\t\t\t\t\t";
  5843.         // line 4112
  5844.         if ((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'4112$this->source); })()), "SaleType", [], "any"falsefalsefalse4112), "id", [], "any"falsefalsefalse4112) == 5)) {
  5845.             // line 4113
  5846.             echo "
  5847. \t\t\t\t\t\t\t";
  5848.             // line 4115
  5849.             echo "\t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  5850. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">ステップ</div>
  5851. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  5852. \t\t\t\t\t\t\t    ";
  5853.             // line 4118
  5854.             $context["step_yes_checked"] = (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4118$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "deck_step", [], "any"truetruefalse4118)) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4118$this->source); })()), "deck_step", [], "any"falsefalsefalse4118) == "必要"));
  5855.             // line 4119
  5856.             echo "\t\t\t\t\t\t\t    ";
  5857.             $context["step_no_checked"] = ((( !(isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4119$this->source); })()) ||  !twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "deck_step", [], "any"truetruefalse4119)) || (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4119$this->source); })()), "deck_step", [], "any"falsefalsefalse4119) == "不要")) ||  !twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4119$this->source); })()), "deck_step", [], "any"falsefalsefalse4119));
  5858.             // line 4120
  5859.             echo "\t\t\t\t\t\t\t    <label class=\"opt-btn";
  5860.             if ((isset($context["step_yes_checked"]) || array_key_exists("step_yes_checked"$context) ? $context["step_yes_checked"] : (function () { throw new RuntimeError('Variable "step_yes_checked" does not exist.'4120$this->source); })())) {
  5861.                 echo " is-selected";
  5862.             }
  5863.             echo "\"
  5864. \t\t\t\t\t\t\t           onclick=\"mitsumori_simulation('op0','deck_step_yes');\">
  5865. \t\t\t\t\t\t\t      <input type=\"radio\" name=\"deck_step\" id=\"deck_step_yes\" value=\"必要\"
  5866. \t\t\t\t\t\t\t             ";
  5867.             // line 4123
  5868.             if ((isset($context["step_yes_checked"]) || array_key_exists("step_yes_checked"$context) ? $context["step_yes_checked"] : (function () { throw new RuntimeError('Variable "step_yes_checked" does not exist.'4123$this->source); })())) {
  5869.                 echo "checked";
  5870.             }
  5871.             echo ">
  5872. \t\t\t\t\t\t\t      必要
  5873. \t\t\t\t\t\t\t    </label>
  5874. \t\t\t\t\t\t\t    <label class=\"opt-btn";
  5875.             // line 4126
  5876.             if ((isset($context["step_no_checked"]) || array_key_exists("step_no_checked"$context) ? $context["step_no_checked"] : (function () { throw new RuntimeError('Variable "step_no_checked" does not exist.'4126$this->source); })())) {
  5877.                 echo " is-selected";
  5878.             }
  5879.             echo "\"
  5880. \t\t\t\t\t\t\t           onclick=\"mitsumori_simulation('op0','deck_step_no');\">
  5881. \t\t\t\t\t\t\t      <input type=\"radio\" name=\"deck_step\" id=\"deck_step_no\" value=\"不要\"
  5882. \t\t\t\t\t\t\t             ";
  5883.             // line 4129
  5884.             if ((isset($context["step_no_checked"]) || array_key_exists("step_no_checked"$context) ? $context["step_no_checked"] : (function () { throw new RuntimeError('Variable "step_no_checked" does not exist.'4129$this->source); })())) {
  5885.                 echo "checked";
  5886.             }
  5887.             echo ">
  5888. \t\t\t\t\t\t\t      不要
  5889. \t\t\t\t\t\t\t    </label>
  5890. \t\t\t\t\t\t\t  </div>
  5891. \t\t\t\t\t\t\t  <div class=\"opt-survey-note-wd-step\" style=\"font-size:12px;color:#c00;margin-top:6px;";
  5892.             // line 4133
  5893.             if ( !(isset($context["step_yes_checked"]) || array_key_exists("step_yes_checked"$context) ? $context["step_yes_checked"] : (function () { throw new RuntimeError('Variable "step_yes_checked" does not exist.'4133$this->source); })())) {
  5894.                 echo "display:none;";
  5895.             }
  5896.             echo "\">
  5897. \t\t\t\t\t\t\t    ※ 現場調査後に正式お見積もりさせていただきます。
  5898. \t\t\t\t\t\t\t  </div>
  5899. \t\t\t\t\t\t\t</div>
  5900. \t\t\t\t\t\t\t";
  5901.             // line 4139
  5902.             echo "\t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  5903. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">デッキフェンス</div>
  5904. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  5905. \t\t\t\t\t\t\t    ";
  5906.             // line 4142
  5907.             $context["fence_yes_checked"] = (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4142$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "deck_fence", [], "any"truetruefalse4142)) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4142$this->source); })()), "deck_fence", [], "any"falsefalsefalse4142) == "必要"));
  5908.             // line 4143
  5909.             echo "\t\t\t\t\t\t\t    ";
  5910.             $context["fence_no_checked"] = ((( !(isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4143$this->source); })()) ||  !twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "deck_fence", [], "any"truetruefalse4143)) || (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4143$this->source); })()), "deck_fence", [], "any"falsefalsefalse4143) == "不要")) ||  !twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4143$this->source); })()), "deck_fence", [], "any"falsefalsefalse4143));
  5911.             // line 4144
  5912.             echo "\t\t\t\t\t\t\t    <label class=\"opt-btn";
  5913.             if ((isset($context["fence_yes_checked"]) || array_key_exists("fence_yes_checked"$context) ? $context["fence_yes_checked"] : (function () { throw new RuntimeError('Variable "fence_yes_checked" does not exist.'4144$this->source); })())) {
  5914.                 echo " is-selected";
  5915.             }
  5916.             echo "\"
  5917. \t\t\t\t\t\t\t           onclick=\"mitsumori_simulation('op1','deck_fence_yes');\">
  5918. \t\t\t\t\t\t\t      <input type=\"radio\" name=\"deck_fence\" id=\"deck_fence_yes\" value=\"必要\"
  5919. \t\t\t\t\t\t\t             ";
  5920.             // line 4147
  5921.             if ((isset($context["fence_yes_checked"]) || array_key_exists("fence_yes_checked"$context) ? $context["fence_yes_checked"] : (function () { throw new RuntimeError('Variable "fence_yes_checked" does not exist.'4147$this->source); })())) {
  5922.                 echo "checked";
  5923.             }
  5924.             echo ">
  5925. \t\t\t\t\t\t\t      必要
  5926. \t\t\t\t\t\t\t    </label>
  5927. \t\t\t\t\t\t\t    <label class=\"opt-btn";
  5928.             // line 4150
  5929.             if ((isset($context["fence_no_checked"]) || array_key_exists("fence_no_checked"$context) ? $context["fence_no_checked"] : (function () { throw new RuntimeError('Variable "fence_no_checked" does not exist.'4150$this->source); })())) {
  5930.                 echo " is-selected";
  5931.             }
  5932.             echo "\"
  5933. \t\t\t\t\t\t\t           onclick=\"mitsumori_simulation('op1','deck_fence_no');\">
  5934. \t\t\t\t\t\t\t      <input type=\"radio\" name=\"deck_fence\" id=\"deck_fence_no\" value=\"不要\"
  5935. \t\t\t\t\t\t\t             ";
  5936.             // line 4153
  5937.             if ((isset($context["fence_no_checked"]) || array_key_exists("fence_no_checked"$context) ? $context["fence_no_checked"] : (function () { throw new RuntimeError('Variable "fence_no_checked" does not exist.'4153$this->source); })())) {
  5938.                 echo "checked";
  5939.             }
  5940.             echo ">
  5941. \t\t\t\t\t\t\t      不要
  5942. \t\t\t\t\t\t\t    </label>
  5943. \t\t\t\t\t\t\t  </div>
  5944. \t\t\t\t\t\t\t  <div class=\"opt-survey-note-wd-fence\" style=\"font-size:12px;color:#c00;margin-top:6px;";
  5945.             // line 4157
  5946.             if ( !(isset($context["fence_yes_checked"]) || array_key_exists("fence_yes_checked"$context) ? $context["fence_yes_checked"] : (function () { throw new RuntimeError('Variable "fence_yes_checked" does not exist.'4157$this->source); })())) {
  5947.                 echo "display:none;";
  5948.             }
  5949.             echo "\">
  5950. \t\t\t\t\t\t\t    ※ 現場調査後に正式お見積もりさせていただきます。
  5951. \t\t\t\t\t\t\t  </div>
  5952. \t\t\t\t\t\t\t</div>
  5953. \t\t\t\t\t\t";
  5954.         }
  5955.         // line 4163
  5956.         echo "
  5957. \t\t\t\t\t\t<!-- 6: 施工見積(芝生・枚数・数量買い) -->
  5958. \t\t\t\t\t\t";
  5959.         // line 4165
  5960.         if ((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'4165$this->source); })()), "SaleType", [], "any"falsefalsefalse4165), "id", [], "any"falsefalsefalse4165) == 6)) {
  5961.             // line 4166
  5962.             echo "
  5963. \t\t\t\t\t\t\t";
  5964.             // line 4168
  5965.             echo "\t\t\t\t\t\t\t";
  5966.             if ((((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'4168$this->source); })()) && twig_length_filter($this->env, (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'4168$this->source); })()))) && (twig_join_filter((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'4168$this->source); })())) != ""))) {
  5967.                 // line 4169
  5968.                 echo "\t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  5969. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">規格";
  5970.                 // line 4170
  5971.                 if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4170$this->source); })()) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4170$this->source); })()), "pm", [], "any"falsefalsefalse4170))) {
  5972.                     echo ": <span>";
  5973.                     echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4170$this->source); })()), "pm", [], "any"falsefalsefalse4170), "html"nulltrue);
  5974.                     echo "</span>";
  5975.                 }
  5976.                 echo "</div>
  5977. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  5978. \t\t\t\t\t\t\t    ";
  5979.                 // line 4172
  5980.                 $context["idx"] = 0;
  5981.                 // line 4173
  5982.                 echo "\t\t\t\t\t\t\t    ";
  5983.                 $context['_parent'] = $context;
  5984.                 $context['_seq'] = twig_ensure_traversable((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'4173$this->source); })()));
  5985.                 foreach ($context['_seq'] as $context["_key"] => $context["pm_val"]) {
  5986.                     if ($context["pm_val"]) {
  5987.                         $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4173$this->source); })()) + 1);
  5988.                         // line 4174
  5989.                         echo "\t\t\t\t\t\t\t      <label class=\"opt-btn";
  5990.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4174$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4174$this->source); })()), "pm", [], "any"falsefalsefalse4174) == $context["pm_val"])) || (twig_length_filter($this->env, (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'4174$this->source); })())) == 1))) {
  5991.                             echo " is-selected";
  5992.                         }
  5993.                         echo "\"
  5994. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('pm','pm6_";
  5995.                         // line 4175
  5996.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4175$this->source); })()), "html"nulltrue);
  5997.                         echo "');\">
  5998. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"pm\" id=\"pm6_";
  5999.                         // line 4176
  6000.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4176$this->source); })()), "html"nulltrue);
  6001.                         echo "\" value=\"";
  6002.                         echo twig_escape_filter($this->env$context["pm_val"], "html"nulltrue);
  6003.                         echo "\"
  6004. \t\t\t\t\t\t\t               ";
  6005.                         // line 4177
  6006.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4177$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4177$this->source); })()), "pm", [], "any"falsefalsefalse4177) == $context["pm_val"])) || (twig_length_filter($this->env, (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'4177$this->source); })())) == 1))) {
  6007.                             echo "checked";
  6008.                         }
  6009.                         echo ">
  6010. \t\t\t\t\t\t\t        ";
  6011.                         // line 4178
  6012.                         echo twig_escape_filter($this->env$context["pm_val"], "html"nulltrue);
  6013.                         echo "
  6014. \t\t\t\t\t\t\t      </label>
  6015. \t\t\t\t\t\t\t    ";
  6016.                     }
  6017.                 }
  6018.                 $_parent $context['_parent'];
  6019.                 unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pm_val'], $context['_parent'], $context['loop']);
  6020.                 $context array_intersect_key($context$_parent) + $_parent;
  6021.                 // line 4181
  6022.                 echo "\t\t\t\t\t\t\t  </div>
  6023. \t\t\t\t\t\t\t</div>
  6024. \t\t\t\t\t\t\t";
  6025.             }
  6026.             // line 4184
  6027.             echo "
  6028. \t\t\t\t\t\t\t";
  6029.             // line 4187
  6030.             echo "\t\t\t\t\t\t\t";
  6031.             if ((((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'4187$this->source); })()) && twig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'4187$this->source); })()))) && (twig_join_filter((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'4187$this->source); })())) != ""))) {
  6032.                 // line 4188
  6033.                 echo "\t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  6034. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">芝の幅";
  6035.                 // line 4189
  6036.                 if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4189$this->source); })()) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4189$this->source); })()), "pw", [], "any"falsefalsefalse4189))) {
  6037.                     echo ": <span>";
  6038.                     echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4189$this->source); })()), "pw", [], "any"falsefalsefalse4189), "html"nulltrue);
  6039.                     echo "</span>";
  6040.                 }
  6041.                 echo "</div>
  6042. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  6043. \t\t\t\t\t\t\t    ";
  6044.                 // line 4191
  6045.                 $context["idx"] = 0;
  6046.                 // line 4192
  6047.                 echo "\t\t\t\t\t\t\t    ";
  6048.                 $context['_parent'] = $context;
  6049.                 $context['_seq'] = twig_ensure_traversable((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'4192$this->source); })()));
  6050.                 foreach ($context['_seq'] as $context["_key"] => $context["pw_val"]) {
  6051.                     if ($context["pw_val"]) {
  6052.                         $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4192$this->source); })()) + 1);
  6053.                         // line 4193
  6054.                         echo "\t\t\t\t\t\t\t      <label class=\"opt-btn";
  6055.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4193$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4193$this->source); })()), "pw", [], "any"falsefalsefalse4193) == $context["pw_val"])) || (twig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'4193$this->source); })())) == 1))) {
  6056.                             echo " is-selected";
  6057.                         }
  6058.                         echo "\"
  6059. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('pw','pw6_";
  6060.                         // line 4194
  6061.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4194$this->source); })()), "html"nulltrue);
  6062.                         echo "');\">
  6063. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"pw\" id=\"pw6_";
  6064.                         // line 4195
  6065.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4195$this->source); })()), "html"nulltrue);
  6066.                         echo "\" value=\"";
  6067.                         echo twig_escape_filter($this->env$context["pw_val"], "html"nulltrue);
  6068.                         echo "\"
  6069. \t\t\t\t\t\t\t               ";
  6070.                         // line 4196
  6071.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4196$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4196$this->source); })()), "pw", [], "any"falsefalsefalse4196) == $context["pw_val"])) || (twig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'4196$this->source); })())) == 1))) {
  6072.                             echo "checked";
  6073.                         }
  6074.                         echo ">
  6075. \t\t\t\t\t\t\t        ";
  6076.                         // line 4197
  6077.                         echo twig_escape_filter($this->env$context["pw_val"], "html"nulltrue);
  6078.                         echo "
  6079. \t\t\t\t\t\t\t      </label>
  6080. \t\t\t\t\t\t\t    ";
  6081.                     }
  6082.                 }
  6083.                 $_parent $context['_parent'];
  6084.                 unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pw_val'], $context['_parent'], $context['loop']);
  6085.                 $context array_intersect_key($context$_parent) + $_parent;
  6086.                 // line 4200
  6087.                 echo "\t\t\t\t\t\t\t  </div>
  6088. \t\t\t\t\t\t\t</div>
  6089. \t\t\t\t\t\t\t";
  6090.             }
  6091.             // line 4203
  6092.             echo "
  6093. \t\t\t\t\t\t\t";
  6094.             // line 4205
  6095.             echo "\t\t\t\t\t\t\t";
  6096.             $context["_roll_h"] = (((array_key_exists("p_h"$context) && twig_length_filter($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'4205$this->source); })())))) ? (twig_first($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'4205$this->source); })()))) : (""));
  6097.             // line 4206
  6098.             echo "\t\t\t\t\t\t\t";
  6099.             if ((isset($context["_roll_h"]) || array_key_exists("_roll_h"$context) ? $context["_roll_h"] : (function () { throw new RuntimeError('Variable "_roll_h" does not exist.'4206$this->source); })())) {
  6100.                 // line 4207
  6101.                 echo "\t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  6102. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">1ロールの長さ:<span style=\"font-weight:bold;\">";
  6103.                 // line 4208
  6104.                 if (twig_in_filter("cm", (isset($context["_roll_h"]) || array_key_exists("_roll_h"$context) ? $context["_roll_h"] : (function () { throw new RuntimeError('Variable "_roll_h" does not exist.'4208$this->source); })()))) {
  6105.                     echo twig_escape_filter($this->env, (twig_trim_filter(twig_replace_filter((isset($context["_roll_h"]) || array_key_exists("_roll_h"$context) ? $context["_roll_h"] : (function () { throw new RuntimeError('Variable "_roll_h" does not exist.'4208$this->source); })()), ["cm" => """," => ""])) / 100), "html"nulltrue);
  6106.                     echo "m";
  6107.                 } else {
  6108.                     echo twig_escape_filter($this->env, (isset($context["_roll_h"]) || array_key_exists("_roll_h"$context) ? $context["_roll_h"] : (function () { throw new RuntimeError('Variable "_roll_h" does not exist.'4208$this->source); })()), "html"nulltrue);
  6109.                 }
  6110.                 echo "</span></div>
  6111. \t\t\t\t\t\t\t</div>
  6112. \t\t\t\t\t\t\t";
  6113.             }
  6114.             // line 4211
  6115.             echo "
  6116. \t\t\t\t\t\t\t";
  6117.             // line 4214
  6118.             echo "\t\t\t\t\t\t\t<div class=\"form-group row mt-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  6119. \t\t\t\t\t\t\t  <label class=\"col-4 col-form-label\">施工サイズ</label>
  6120. \t\t\t\t\t\t\t  <div class=\"col-8\">
  6121. \t\t\t\t\t\t\t    <div class=\"input-group\">
  6122. \t\t\t\t\t\t\t      <input type=\"number\" name=\"tf_len\" id=\"tf_len\"
  6123. \t\t\t\t\t\t\t        class=\"form-control\"
  6124. \t\t\t\t\t\t\t        value=\"";
  6125.             // line 4220
  6126.             echo twig_escape_filter($this->env, ((twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "tf_len", [], "any"truetruefalse4220)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "tf_len", [], "any"falsefalsefalse4220), "")) : ("")), "html"nulltrue);
  6127.             echo "\"
  6128. \t\t\t\t\t\t\t        placeholder=\"縦\" min=\"0.1\" step=\"0.1\"
  6129. \t\t\t\t\t\t\t        onchange=\"mitsumori_simulation('tf_len','tf_len');\">
  6130. \t\t\t\t\t\t\t      <span class=\"input-group-text\">m&nbsp;×</span>
  6131. \t\t\t\t\t\t\t      <input type=\"number\" name=\"tf_wid\" id=\"tf_wid\"
  6132. \t\t\t\t\t\t\t        class=\"form-control\"
  6133. \t\t\t\t\t\t\t        value=\"";
  6134.             // line 4226
  6135.             echo twig_escape_filter($this->env, ((twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "tf_wid", [], "any"truetruefalse4226)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "tf_wid", [], "any"falsefalsefalse4226), "")) : ("")), "html"nulltrue);
  6136.             echo "\"
  6137. \t\t\t\t\t\t\t        placeholder=\"横\" min=\"0.1\" step=\"0.1\"
  6138. \t\t\t\t\t\t\t        onchange=\"mitsumori_simulation('tf_wid','tf_wid');\">
  6139. \t\t\t\t\t\t\t      <span class=\"input-group-text\">m</span>
  6140. \t\t\t\t\t\t\t    </div>
  6141. \t\t\t\t\t\t\t    ";
  6142.             // line 4232
  6143.             echo "\t\t\t\t\t\t\t    <input type=\"hidden\" name=\"area\" id=\"area\" value=\"";
  6144.             echo twig_escape_filter($this->env, ((twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "area", [], "any"truetruefalse4232)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "area", [], "any"falsefalsefalse4232), "")) : ("")), "html"nulltrue);
  6145.             echo "\">
  6146. \t\t\t\t\t\t\t    ";
  6147.             // line 4235
  6148.             echo "\t\t\t\t\t\t\t    <div style=\"margin-top:10px;display:inline-block;background:#fff3cd;border:1px solid #ffe69c;border-radius:6px;padding:8px 14px;font-size:16px;color:#c00;font-weight:bold;\">
  6149. \t\t\t\t\t\t\t      必要枚数:<input type=\"number\" name=\"tf_qty\" id=\"tf_qty\"
  6150. \t\t\t\t\t\t\t        value=\"";
  6151.             // line 4237
  6152.             echo twig_escape_filter($this->env, ((twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "tf_qty", [], "any"truetruefalse4237)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "tf_qty", [], "any"falsefalsefalse4237), "1")) : ("1")), "html"nulltrue);
  6153.             echo "\" min=\"1\" step=\"1\"
  6154. \t\t\t\t\t\t\t        style=\"width:80px;font-size:22px;font-weight:bold;color:#c00;text-align:right;border:1px solid #ffe69c;border-radius:4px;padding:2px 6px;\"
  6155. \t\t\t\t\t\t\t        onchange=\"mitsumori_simulation('tf_qty','tf_qty');\"> 枚
  6156. \t\t\t\t\t\t\t    </div>
  6157. \t\t\t\t\t\t\t    <div style=\"margin-top:6px;font-size:12px;color:#666;\">※ 施工サイズを入力すると必要枚数を自動計算します。サイズが分からない場合は枚数を直接ご指定ください。</div>
  6158. \t\t\t\t\t\t\t  </div>
  6159. \t\t\t\t\t\t\t</div>
  6160. \t\t\t\t\t\t";
  6161.         }
  6162.         // line 4246
  6163.         echo "
  6164. \t\t\t\t\t\t<!-- 7: 施工見積(数量買い・基本工事費固定) -->
  6165. \t\t\t\t\t\t";
  6166.         // line 4248
  6167.         if ((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'4248$this->source); })()), "SaleType", [], "any"falsefalsefalse4248), "id", [], "any"falsefalsefalse4248) == 7)) {
  6168.             // line 4249
  6169.             echo "\t\t\t\t\t\t\t";
  6170.             // line 4250
  6171.             echo "\t\t\t\t\t\t\t<div class=\"form-group row mt-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  6172. \t\t\t\t\t\t\t  <label class=\"col-4 col-form-label\">個数</label>
  6173. \t\t\t\t\t\t\t  <div class=\"col-4\">
  6174. \t\t\t\t\t\t\t    <div class=\"input-group mb-3\">
  6175. \t\t\t\t\t\t\t      <input type=\"number\" name=\"suuryou\" id=\"suuryou\" class=\"form-control\"
  6176. \t\t\t\t\t\t\t        value=\"";
  6177.             // line 4255
  6178.             echo twig_escape_filter($this->env, ((twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "suuryou", [], "any"truetruefalse4255)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "suuryou", [], "any"falsefalsefalse4255), "1")) : ("1")), "html"nulltrue);
  6179.             echo "\" min=\"1\" max=\"100\"
  6180. \t\t\t\t\t\t\t        onchange=\"mitsumori_simulation('suuryou','suuryou');\">
  6181. \t\t\t\t\t\t\t      <span class=\"input-group-text\">個</span>
  6182. \t\t\t\t\t\t\t    </div>
  6183. \t\t\t\t\t\t\t  </div>
  6184. \t\t\t\t\t\t\t  <div class=\"col-4\">
  6185. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-info\" onclick=\"suuryou(+1);\">+</button>
  6186. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-danger\" onclick=\"suuryou(-1);\">ー</button>
  6187. \t\t\t\t\t\t\t  </div>
  6188. \t\t\t\t\t\t\t</div>
  6189. \t\t\t\t\t\t";
  6190.         }
  6191.         // line 4266
  6192.         echo "
  6193. \t\t\t\t\t\t<!-- 9: 商品のみ購入 -->
  6194. \t\t\t\t\t\t";
  6195.         // line 4268
  6196.         if ((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'4268$this->source); })()), "SaleType", [], "any"falsefalsefalse4268), "id", [], "any"falsefalsefalse4268) == 9)) {
  6197.             // line 4269
  6198.             echo "\t\t\t\t\t\t\t<div class=\"form-group row mt-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  6199. \t\t\t\t\t\t\t  <label class=\"col-4 col-form-label\">数量</label>
  6200. \t\t\t\t\t\t\t  <div class=\"col-4\">
  6201. \t\t\t\t\t\t\t    <div class=\"input-group mb-3\">
  6202. \t\t\t\t\t\t\t      <input type=\"number\" name=\"quantity_only\" id=\"quantity_only\" class=\"form-control\" value=\"1\" min=\"1\" onchange=\"\$('#quantity').val(this.value);\">
  6203. \t\t\t\t\t\t\t      <span class=\"input-group-text\">個</span>
  6204. \t\t\t\t\t\t\t    </div>
  6205. \t\t\t\t\t\t\t  </div>
  6206. \t\t\t\t\t\t\t  <div class=\"col-4\">
  6207. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-info\" onclick=\"quantityOnly(+1);\">+</button>
  6208. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-danger\" onclick=\"quantityOnly(-1);\">ー</button>
  6209. \t\t\t\t\t\t\t  </div>
  6210. \t\t\t\t\t\t\t</div>
  6211. \t\t\t\t\t\t";
  6212.         }
  6213.         // line 4283
  6214.         echo "
  6215. \t\t\t\t\t    <div class=\"row\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\"><label class=\"col-12 col-form-label\">取り付け工事のご希望に関してお答えください。</label></div>
  6216. \t\t\t\t\t\t";
  6217.         // line 4291
  6218.         echo "\t\t\t\t\t\t";
  6219.         $context["is_gs"] = false;
  6220.         // line 4292
  6221.         echo "\t\t\t\t\t\t";
  6222.         $context["is_cg"] = false;
  6223.         // line 4293
  6224.         echo "\t\t\t\t\t\t";
  6225.         if ( !twig_test_empty(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'4293$this->source); })()), "ProductCategories", [], "any"falsefalsefalse4293))) {
  6226.             // line 4294
  6227.             echo "\t\t\t\t\t\t\t";
  6228.             $context['_parent'] = $context;
  6229.             $context['_seq'] = twig_ensure_traversable(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'4294$this->source); })()), "ProductCategories", [], "any"falsefalsefalse4294));
  6230.             foreach ($context['_seq'] as $context["_key"] => $context["ProductCategory"]) {
  6231.                 // line 4295
  6232.                 echo "\t\t\t\t\t\t\t\t";
  6233.                 if ((twig_get_attribute($this->env$this->source$context["ProductCategory"], "category_id", [], "any"falsefalsefalse4295) == 27)) {
  6234.                     $context["is_gs"] = true;
  6235.                 }
  6236.                 // line 4296
  6237.                 echo "\t\t\t\t\t\t\t\t";
  6238.                 if ((twig_get_attribute($this->env$this->source$context["ProductCategory"], "category_id", [], "any"falsefalsefalse4296) == 9)) {
  6239.                     $context["is_cg"] = true;
  6240.                 }
  6241.                 // line 4297
  6242.                 echo "\t\t\t\t\t\t\t";
  6243.             }
  6244.             $_parent $context['_parent'];
  6245.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['ProductCategory'], $context['_parent'], $context['loop']);
  6246.             $context array_intersect_key($context$_parent) + $_parent;
  6247.             // line 4298
  6248.             echo "\t\t\t\t\t\t";
  6249.         }
  6250.         // line 4299
  6251.         echo "\t\t\t\t\t\t";
  6252.         $context['_parent'] = $context;
  6253.         $context['_seq'] = twig_ensure_traversable(range(010));
  6254.         foreach ($context['_seq'] as $context["_key"] => $context["i"]) {
  6255.             // line 4300
  6256.             echo "\t\t\t\t\t\t\t";
  6257.             if (((isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4300$this->source); })()) && (twig_length_filter($this->env, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4300$this->source); })())) >= ($context["i"] + 1)))) {
  6258.                 // line 4301
  6259.                 echo "\t\t\t\t\t\t\t";
  6260.                 if (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4301$this->source); })()), $context["i"], [], "array"falsefalsefalse4301), "name", [], "array"falsefalsefalse4301)) {
  6261.                     // line 4302
  6262.                     echo "\t\t\t\t\t\t\t";
  6263.                     $context["hide_opt"] = false;
  6264.                     // line 4303
  6265.                     echo "\t\t\t\t\t\t\t";
  6266.                     if (((isset($context["is_gs"]) || array_key_exists("is_gs"$context) ? $context["is_gs"] : (function () { throw new RuntimeError('Variable "is_gs" does not exist.'4303$this->source); })()) && (preg_match("/撤去/"twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4303$this->source); })()), $context["i"], [], "array"falsefalsefalse4303), "name", [], "array"falsefalsefalse4303)) || preg_match("/残土/"twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4303$this->source); })()), $context["i"], [], "array"falsefalsefalse4303), "name", [], "array"falsefalsefalse4303))))) {
  6267.                         // line 4304
  6268.                         echo "\t\t\t\t\t\t\t\t";
  6269.                         $context["hide_opt"] = true;
  6270.                         // line 4305
  6271.                         echo "\t\t\t\t\t\t\t";
  6272.                     }
  6273.                     // line 4306
  6274.                     echo "\t\t\t\t\t\t\t";
  6275.                     if (((isset($context["is_cg"]) || array_key_exists("is_cg"$context) ? $context["is_cg"] : (function () { throw new RuntimeError('Variable "is_cg" does not exist.'4306$this->source); })()) && preg_match("/残土/"twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4306$this->source); })()), $context["i"], [], "array"falsefalsefalse4306), "name", [], "array"falsefalsefalse4306)))) {
  6276.                         // line 4307
  6277.                         echo "\t\t\t\t\t\t\t\t";
  6278.                         $context["hide_opt"] = true;
  6279.                         // line 4308
  6280.                         echo "\t\t\t\t\t\t\t";
  6281.                     }
  6282.                     // line 4309
  6283.                     echo "\t\t\t\t\t\t\t";
  6284.                     if ( !(isset($context["hide_opt"]) || array_key_exists("hide_opt"$context) ? $context["hide_opt"] : (function () { throw new RuntimeError('Variable "hide_opt" does not exist.'4309$this->source); })())) {
  6285.                         // line 4310
  6286.                         echo "\t\t\t\t\t\t\t";
  6287.                         // line 4312
  6288.                         echo "\t\t\t\t\t\t\t";
  6289.                         $context["is_removal_unknown"] = (((((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, ($context["op"] ?? null), $context["i"], [], "array"falsetruefalse4312), "price", [], "array"truetruefalse4312)) ? (_twig_default_filter(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, ($context["op"] ?? null), $context["i"], [], "array"falsetruefalse4312), "price", [], "array"falsefalsefalse4312), 0)) : (0)) == 0) || (((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, ($context["op"] ?? null), $context["i"], [], "array"falsetruefalse4312), "price", [], "array"truetruefalse4312)) ? (_twig_default_filter(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, ($context["op"] ?? null), $context["i"], [], "array"falsetruefalse4312), "price", [], "array"falsefalsefalse4312), "0")) : ("0")) == "0")) && ((preg_match("/解体/"twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source,                         // line 4313
  6290. (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4313$this->source); })()), $context["i"], [], "array"falsefalsefalse4313), "name", [], "array"falsefalsefalse4313)) || preg_match("/撤去/"twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4313$this->source); })()), $context["i"], [], "array"falsefalsefalse4313), "name", [], "array"falsefalsefalse4313))) || preg_match("/設置場所/"twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4313$this->source); })()), $context["i"], [], "array"falsefalsefalse4313), "name", [], "array"falsefalsefalse4313))));
  6291.                         // line 4314
  6292.                         echo "\t\t\t\t\t\t\t";
  6293.                         // line 4315
  6294.                         echo "\t\t\t\t\t\t\t";
  6295.                         $context["is_tf_kouji"] = ((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'4315$this->source); })()), "SaleType", [], "any"falsefalsefalse4315), "id", [], "any"falsefalsefalse4315) == 6) && preg_match("/取り付け工事/"twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4315$this->source); })()), $context["i"], [], "array"falsefalsefalse4315), "name", [], "array"falsefalsefalse4315)));
  6296.                         // line 4316
  6297.                         echo "\t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-3\" data-op-idx=\"";
  6298.                         echo twig_escape_filter($this->env$context["i"], "html"nulltrue);
  6299.                         echo "\" data-op-name=\"";
  6300.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4316$this->source); })()), $context["i"], [], "array"falsefalsefalse4316), "name", [], "array"falsefalsefalse4316), "html_attr");
  6301.                         echo "\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  6302. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">";
  6303.                         // line 4318
  6304.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4318$this->source); })()), $context["i"], [], "array"falsefalsefalse4318), "name", [], "array"falsefalsefalse4318), "html"nulltrue);
  6305.                         if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4318$this->source); })()) && twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4318$this->source); })()), "op", [], "any"falsefalsefalse4318), $context["i"], [], "array"falsefalsefalse4318))) {
  6306.                             echo ": <span>";
  6307.                             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4318$this->source); })()), "op", [], "any"falsefalsefalse4318), $context["i"], [], "array"falsefalsefalse4318), "html"nulltrue);
  6308.                             echo "</span>";
  6309.                         }
  6310.                         echo "</div>
  6311. \t\t\t\t\t\t\t  ";
  6312.                         // line 4319
  6313.                         if (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4319$this->source); })()), $context["i"], [], "array"falsefalsefalse4319), "comment", [], "array"falsefalsefalse4319)) {
  6314.                             echo "<div class=\"opt-comment\" style=\"font-size:12px;color:#666;margin:4px 0 6px;\">";
  6315.                             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4319$this->source); })()), $context["i"], [], "array"falsefalsefalse4319), "comment", [], "array"falsefalsefalse4319), "html"nulltrue);
  6316.                             echo "</div>";
  6317.                         }
  6318.                         // line 4320
  6319.                         echo "\t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  6320. \t\t\t\t\t\t\t    ";
  6321.                         // line 4323
  6322.                         echo "\t\t\t\t\t\t\t    <label class=\"opt-btn";
  6323.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4323$this->source); })()) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4323$this->source); })()), "op", [], "any"falsefalsefalse4323), $context["i"], [], "array"falsefalsefalse4323) == twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4323$this->source); })()), $context["i"], [], "array"falsefalsefalse4323), "on", [], "array"falsefalsefalse4323))) ||  !twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4323$this->source); })()), $context["i"], [], "array"falsefalsefalse4323), "off", [], "array"falsefalsefalse4323))) {
  6324.                             echo " is-selected";
  6325.                         }
  6326.                         echo "\"
  6327. \t\t\t\t\t\t\t           onclick=\"mitsumori_simulation('op";
  6328.                         // line 4324
  6329.                         echo twig_escape_filter($this->env$context["i"], "html"nulltrue);
  6330.                         echo "','op";
  6331.                         echo twig_escape_filter($this->env$context["i"], "html"nulltrue);
  6332.                         echo "_1');\">
  6333. \t\t\t\t\t\t\t      <input type=\"radio\" name=\"op";
  6334.                         // line 4325
  6335.                         echo twig_escape_filter($this->env$context["i"], "html"nulltrue);
  6336.                         echo "\" id=\"op";
  6337.                         echo twig_escape_filter($this->env$context["i"], "html"nulltrue);
  6338.                         echo "_1\" value=\"";
  6339.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4325$this->source); })()), $context["i"], [], "array"falsefalsefalse4325), "on", [], "array"falsefalsefalse4325), "html"nulltrue);
  6340.                         echo "\" ";
  6341.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4325$this->source); })()) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4325$this->source); })()), "op", [], "any"falsefalsefalse4325), $context["i"], [], "array"falsefalsefalse4325) == twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4325$this->source); })()), $context["i"], [], "array"falsefalsefalse4325), "on", [], "array"falsefalsefalse4325))) ||  !twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4325$this->source); })()), $context["i"], [], "array"falsefalsefalse4325), "off", [], "array"falsefalsefalse4325))) {
  6342.                             echo "checked";
  6343.                         }
  6344.                         echo ">
  6345. \t\t\t\t\t\t\t      ";
  6346.                         // line 4326
  6347.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4326$this->source); })()), $context["i"], [], "array"falsefalsefalse4326), "on", [], "array"falsefalsefalse4326), "html"nulltrue);
  6348.                         echo "
  6349. \t\t\t\t\t\t\t    </label>
  6350. \t\t\t\t\t\t\t    ";
  6351.                         // line 4328
  6352.                         if (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4328$this->source); })()), $context["i"], [], "array"falsefalsefalse4328), "off", [], "array"falsefalsefalse4328)) {
  6353.                             // line 4329
  6354.                             echo "\t\t\t\t\t\t\t    <label class=\"opt-btn";
  6355.                             if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4329$this->source); })()) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4329$this->source); })()), "op", [], "any"falsefalsefalse4329), $context["i"], [], "array"falsefalsefalse4329) == twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4329$this->source); })()), $context["i"], [], "array"falsefalsefalse4329), "off", [], "array"falsefalsefalse4329)))) {
  6356.                                 echo " is-selected";
  6357.                             }
  6358.                             echo "\"
  6359. \t\t\t\t\t\t\t           onclick=\"mitsumori_simulation('op";
  6360.                             // line 4330
  6361.                             echo twig_escape_filter($this->env$context["i"], "html"nulltrue);
  6362.                             echo "','op";
  6363.                             echo twig_escape_filter($this->env$context["i"], "html"nulltrue);
  6364.                             echo "_2');\">
  6365. \t\t\t\t\t\t\t      <input type=\"radio\" name=\"op";
  6366.                             // line 4331
  6367.                             echo twig_escape_filter($this->env$context["i"], "html"nulltrue);
  6368.                             echo "\" id=\"op";
  6369.                             echo twig_escape_filter($this->env$context["i"], "html"nulltrue);
  6370.                             echo "_2\" value=\"";
  6371.                             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4331$this->source); })()), $context["i"], [], "array"falsefalsefalse4331), "off", [], "array"falsefalsefalse4331), "html"nulltrue);
  6372.                             echo "\" ";
  6373.                             if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4331$this->source); })()) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4331$this->source); })()), "op", [], "any"falsefalsefalse4331), $context["i"], [], "array"falsefalsefalse4331) == twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4331$this->source); })()), $context["i"], [], "array"falsefalsefalse4331), "off", [], "array"falsefalsefalse4331)))) {
  6374.                                 echo "checked";
  6375.                             }
  6376.                             echo ">
  6377. \t\t\t\t\t\t\t      ";
  6378.                             // line 4332
  6379.                             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4332$this->source); })()), $context["i"], [], "array"falsefalsefalse4332), "off", [], "array"falsefalsefalse4332), "html"nulltrue);
  6380.                             echo "
  6381. \t\t\t\t\t\t\t    </label>
  6382. \t\t\t\t\t\t\t    ";
  6383.                         }
  6384.                         // line 4335
  6385.                         echo "\t\t\t\t\t\t\t  </div>
  6386. \t\t\t\t\t\t\t  ";
  6387.                         // line 4336
  6388.                         if (((isset($context["is_removal_unknown"]) || array_key_exists("is_removal_unknown"$context) ? $context["is_removal_unknown"] : (function () { throw new RuntimeError('Variable "is_removal_unknown" does not exist.'4336$this->source); })()) || (isset($context["is_tf_kouji"]) || array_key_exists("is_tf_kouji"$context) ? $context["is_tf_kouji"] : (function () { throw new RuntimeError('Variable "is_tf_kouji" does not exist.'4336$this->source); })()))) {
  6389.                             // line 4337
  6390.                             echo "\t\t\t\t\t\t\t  <div class=\"opt-survey-note\" data-op-idx=\"";
  6391.                             echo twig_escape_filter($this->env$context["i"], "html"nulltrue);
  6392.                             echo "\" style=\"font-size:12px;color:#c00;margin-top:6px;";
  6393.                             if ( !((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4337$this->source); })()) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4337$this->source); })()), "op", [], "any"falsefalsefalse4337), $context["i"], [], "array"falsefalsefalse4337) == twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4337$this->source); })()), $context["i"], [], "array"falsefalsefalse4337), "on", [], "array"falsefalsefalse4337)))) {
  6394.                                 echo "display:none;";
  6395.                             }
  6396.                             echo "\">
  6397. \t\t\t\t\t\t\t    ※ 現場調査後に正式お見積もりさせていただきます。
  6398. \t\t\t\t\t\t\t  </div>
  6399. \t\t\t\t\t\t\t  ";
  6400.                         }
  6401.                         // line 4341
  6402.                         echo "\t\t\t\t\t\t\t</div>
  6403. \t\t\t\t\t\t\t";
  6404.                     }
  6405.                     // line 4343
  6406.                     echo "\t\t\t\t\t\t\t";
  6407.                 }
  6408.                 // line 4344
  6409.                 echo "\t\t\t\t\t\t\t";
  6410.             }
  6411.             // line 4345
  6412.             echo "\t\t\t\t\t\t";
  6413.         }
  6414.         $_parent $context['_parent'];
  6415.         unset($context['_seq'], $context['_iterated'], $context['_key'], $context['i'], $context['_parent'], $context['loop']);
  6416.         $context array_intersect_key($context$_parent) + $_parent;
  6417.         // line 4346
  6418.         echo "
  6419. \t\t\t\t\t\t";
  6420.         // line 4350
  6421.         echo "\t\t\t\t\t\t";
  6422.         if ((((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'4350$this->source); })()), "SaleType", [], "any"falsefalsefalse4350), "id", [], "any"falsefalsefalse4350) == 4) && (isset($context["oi"]) || array_key_exists("oi"$context) ? $context["oi"] : (function () { throw new RuntimeError('Variable "oi" does not exist.'4350$this->source); })())) && twig_get_attribute($this->env$this->source, (isset($context["oi"]) || array_key_exists("oi"$context) ? $context["oi"] : (function () { throw new RuntimeError('Variable "oi" does not exist.'4350$this->source); })()), "fe_block", [], "any"falsefalsefalse4350))) {
  6423.             // line 4351
  6424.             echo "\t\t\t\t\t\t<div id=\"fe-block-options\" class=\"form-group mt-3 pb-3\" style=\"display:none;border-bottom:1px solid rgba(0,0,0,.125)\"></div>
  6425. \t\t\t\t\t\t";
  6426.         }
  6427.         // line 4353
  6428.         echo "
  6429. \t\t\t\t\t  </div>
  6430. \t\t\t\t\t  <!-- /.card-body -->
  6431. \t\t\t\t\t</div>
  6432.                     <form action=\"";
  6433.         // line 4359
  6434.         echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getUrl("product_add_cart", ["id" => twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'4359$this->source); })()), "id", [], "any"falsefalsefalse4359)]), "html"nulltrue);
  6435.         echo "\" method=\"post\" id=\"form1\" name=\"form1\">
  6436.                         ";
  6437.         // line 4360
  6438.         if (twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'4360$this->source); })()), "stock_find", [], "any"falsefalsefalse4360)) {
  6439.             // line 4361
  6440.             echo "                            <div class=\"ec-productRole__actions\">
  6441.                                 ";
  6442.             // line 4362
  6443.             if (twig_get_attribute($this->env$this->source, ($context["form"] ?? null), "classcategory_id1", [], "any"truetruefalse4362)) {
  6444.                 // line 4363
  6445.                 echo "                                    <div class=\"ec-select\">
  6446.                                         ";
  6447.                 // line 4364
  6448.                 echo $this->env->getRuntime('Symfony\Component\Form\FormRenderer')->searchAndRenderBlock(twig_get_attribute($this->env$this->source, (isset($context["form"]) || array_key_exists("form"$context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.'4364$this->source); })()), "classcategory_id1", [], "any"falsefalsefalse4364), 'row');
  6449.                 echo "
  6450.                                         ";
  6451.                 // line 4365
  6452.                 echo $this->env->getRuntime('Symfony\Component\Form\FormRenderer')->searchAndRenderBlock(twig_get_attribute($this->env$this->source, (isset($context["form"]) || array_key_exists("form"$context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.'4365$this->source); })()), "classcategory_id1", [], "any"falsefalsefalse4365), 'errors');
  6453.                 echo "
  6454.                                     </div>
  6455.                                     ";
  6456.                 // line 4367
  6457.                 if (twig_get_attribute($this->env$this->source, ($context["form"] ?? null), "classcategory_id2", [], "any"truetruefalse4367)) {
  6458.                     // line 4368
  6459.                     echo "                                        <div class=\"ec-select\">
  6460.                                             ";
  6461.                     // line 4369
  6462.                     echo $this->env->getRuntime('Symfony\Component\Form\FormRenderer')->searchAndRenderBlock(twig_get_attribute($this->env$this->source, (isset($context["form"]) || array_key_exists("form"$context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.'4369$this->source); })()), "classcategory_id2", [], "any"falsefalsefalse4369), 'row');
  6463.                     echo "
  6464.                                             ";
  6465.                     // line 4370
  6466.                     echo $this->env->getRuntime('Symfony\Component\Form\FormRenderer')->searchAndRenderBlock(twig_get_attribute($this->env$this->source, (isset($context["form"]) || array_key_exists("form"$context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.'4370$this->source); })()), "classcategory_id2", [], "any"falsefalsefalse4370), 'errors');
  6467.                     echo "
  6468.                                         </div>
  6469.                                     ";
  6470.                 }
  6471.                 // line 4373
  6472.                 echo "                                ";
  6473.             }
  6474.             // line 4374
  6475.             echo "                                <div class=\"ec-numberInput\">
  6476.                                     ";
  6477.             // line 4375
  6478.             echo $this->env->getRuntime('Symfony\Component\Form\FormRenderer')->searchAndRenderBlock(twig_get_attribute($this->env$this->source, (isset($context["form"]) || array_key_exists("form"$context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.'4375$this->source); })()), "quantity", [], "any"falsefalsefalse4375), 'widget', ["type" => "hidden"]);
  6479.             echo "
  6480.                                     ";
  6481.             // line 4376
  6482.             echo $this->env->getRuntime('Symfony\Component\Form\FormRenderer')->searchAndRenderBlock(twig_get_attribute($this->env$this->source, (isset($context["form"]) || array_key_exists("form"$context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.'4376$this->source); })()), "quantity", [], "any"falsefalsefalse4376), 'errors');
  6483.             echo "
  6484.                                 </div>
  6485.                             </div>
  6486.                         ";
  6487.         } else {
  6488.             // line 4381
  6489.             echo "                            <div class=\"ec-productRole__btn\">
  6490.                                 <button type=\"button\" class=\"ec-blockBtn--action\" disabled=\"disabled\">
  6491.                                     ";
  6492.             // line 4383
  6493.             echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\TranslationExtension']->trans("ただいま品切れ中です。"), "html"nulltrue);
  6494.             echo "
  6495.                                 </button>
  6496.                             </div>
  6497.                         ";
  6498.         }
  6499.         // line 4387
  6500.         echo "                        <div class=\"ec-productRole__btn mt-3\">
  6501.                            <button type=\"submit\" id=\"cart_btn\" class=\"ec-blockBtn--action add-cart\">カートに入れる</button>
  6502.                         </div>
  6503.                         ";
  6504.         // line 4390
  6505.         echo $this->env->getRuntime('Symfony\Component\Form\FormRenderer')->searchAndRenderBlock((isset($context["form"]) || array_key_exists("form"$context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.'4390$this->source); })()), 'rest');
  6506.         echo "
  6507.                     </form>
  6508.                     <div class=\"ec-modal add-cart-modal\">
  6509.                         <div class=\"ec-modal-overlay\">
  6510.                             <div class=\"ec-modal-wrap add-cart-modal__wrap\">
  6511.                                 <span class=\"ec-modal-close\"><span class=\"ec-icon\"><img src=\"";
  6512.         // line 4395
  6513.         echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl("assets/icon/cross-dark.svg"), "html"nulltrue);
  6514.         echo "\" alt=\"\"/></span></span>
  6515.                                 <div id=\"ec-modal-header\" class=\"text-center add-cart-modal__header\">";
  6516.         // line 4396
  6517.         echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\TranslationExtension']->trans("カートに追加しました。"), "html"nulltrue);
  6518.         echo "</div>
  6519.                                 <div class=\"ec-modal-box add-cart-modal__box\">
  6520.                                     <div class=\"ec-role add-cart-modal__actions\">
  6521.                                         <a href=\"";
  6522.         // line 4399
  6523.         echo $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getUrl("cart");
  6524.         echo "\" class=\"ec-inlineBtn--action add-cart-modal__primary\">";
  6525.         echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\TranslationExtension']->trans("カートに進む"), "html"nulltrue);
  6526.         echo "</a>
  6527.                                         <span class=\"ec-inlineBtn--cancel add-cart-modal__secondary\">";
  6528.         // line 4400
  6529.         echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\TranslationExtension']->trans("商品検索を続ける"), "html"nulltrue);
  6530.         echo "</span>
  6531.                                     </div>
  6532.                                 </div>
  6533.                             </div>
  6534.                         </div>
  6535.                     </div>
  6536.                     <div class=\"ec-productRole__description\">";
  6537.         // line 4406
  6538.         echo twig_nl2br(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'4406$this->source); })()), "description_detail", [], "any"falsefalsefalse4406));
  6539.         echo "
  6540.                     </div>
  6541.                     ";
  6542.         // line 4410
  6543.         echo "                    <div class=\"ec-productRole__share\">
  6544.                         <ul class=\"ec-share\">
  6545.                             <li class=\"ec-share__item\">
  6546.                                 <a href=\"https://twitter.com/share?url=";
  6547.         // line 4413
  6548.         echo twig_escape_filter($this->envtwig_urlencode_filter(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["app"]) || array_key_exists("app"$context) ? $context["app"] : (function () { throw new RuntimeError('Variable "app" does not exist.'4413$this->source); })()), "request", [], "any"falsefalsefalse4413), "uri", [], "any"falsefalsefalse4413)), "html"nulltrue);
  6549.         echo "&text=";
  6550.         echo twig_escape_filter($this->envtwig_urlencode_filter(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'4413$this->source); })()), "name", [], "any"falsefalsefalse4413)), "html"nulltrue);
  6551.         echo "\" class=\"ec-share__link ec-share__link--twitter\" target=\"_blank\" rel=\"noreferrer noopener\">
  6552.                                     <i class=\"fab fa-twitter\"></i>
  6553.                                 </a>
  6554.                             </li>
  6555.                             <li class=\"ec-share__item\">
  6556.                                 <a href=\"https://www.facebook.com/sharer/sharer.php?u=";
  6557.         // line 4418
  6558.         echo twig_escape_filter($this->envtwig_urlencode_filter(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["app"]) || array_key_exists("app"$context) ? $context["app"] : (function () { throw new RuntimeError('Variable "app" does not exist.'4418$this->source); })()), "request", [], "any"falsefalsefalse4418), "uri", [], "any"falsefalsefalse4418)), "html"nulltrue);
  6559.         echo "\" class=\"ec-share__link ec-share__link--facebook\" target=\"_blank\" rel=\"noreferrer noopener\">
  6560.                                     <i class=\"fab fa-facebook-f\"></i>
  6561.                                 </a>
  6562.                             </li>
  6563.                             <li class=\"ec-share__item\">
  6564.                                 <a href=\"https://social-plugins.line.me/lineit/share?url=";
  6565.         // line 4423
  6566.         echo twig_escape_filter($this->envtwig_urlencode_filter(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["app"]) || array_key_exists("app"$context) ? $context["app"] : (function () { throw new RuntimeError('Variable "app" does not exist.'4423$this->source); })()), "request", [], "any"falsefalsefalse4423), "uri", [], "any"falsefalsefalse4423)), "html"nulltrue);
  6567.         echo "\" class=\"ec-share__link ec-share__link--line\" target=\"_blank\" rel=\"noreferrer noopener\">
  6568.                                     <i class=\"fab fa-line\"></i>
  6569.                                 </a>
  6570.                             </li>
  6571.                         </ul>
  6572.                     </div>
  6573.                 </div>
  6574. \t\t\t\t";
  6575.         // line 4431
  6576.         echo "\t\t\t\t<div id=\"sp-mitsumori-bar\">
  6577. \t\t\t\t    <div class=\"sp-bar__pricewrap\">
  6578. \t\t\t\t        <div class=\"sp-bar__label\">合計(工事費・税込)</div>
  6579. \t\t\t\t        <div class=\"sp-bar__price\" id=\"sp-mitsumori-price\">---円</div>
  6580. \t\t\t\t    </div>
  6581. \t\t\t\t    <button type=\"button\" class=\"sp-bar__detail-btn\"
  6582. \t\t\t\t            onclick=\"openSpMitsumoriDetail();\" title=\"お見積りの詳細(内訳)を表示\">
  6583. \t\t\t\t        <i class=\"far fa-file-alt\"></i>
  6584. \t\t\t\t        <span>詳細</span>
  6585. \t\t\t\t    </button>
  6586. \t\t\t\t    <button type=\"button\" class=\"sp-bar__btn\"
  6587. \t\t\t\t            onclick=\"document.getElementById('cart_btn2') && document.getElementById('cart_btn2').click();\">
  6588. \t\t\t\t        <i class=\"fas fa-shopping-cart\"></i>
  6589. \t\t\t\t        <span class=\"sp-bar__btn-label\">カートへ</span>
  6590. \t\t\t\t        ";
  6591.         // line 4445
  6592.         $context["spTotalQty"] = $this->extensions['Eccube\Twig\Extension\CartServiceExtension']->get_carts_total_quantity();
  6593.         // line 4446
  6594.         echo "\t\t\t\t        ";
  6595.         if (((isset($context["spTotalQty"]) || array_key_exists("spTotalQty"$context) ? $context["spTotalQty"] : (function () { throw new RuntimeError('Variable "spTotalQty" does not exist.'4446$this->source); })()) > 0)) {
  6596.             // line 4447
  6597.             echo "\t\t\t\t            <span class=\"sp-bar__cart-badge\">";
  6598.             echo twig_escape_filter($this->envtwig_number_format_filter($this->env, (isset($context["spTotalQty"]) || array_key_exists("spTotalQty"$context) ? $context["spTotalQty"] : (function () { throw new RuntimeError('Variable "spTotalQty" does not exist.'4447$this->source); })())), "html"nulltrue);
  6599.             echo "</span>
  6600. \t\t\t\t        ";
  6601.         }
  6602.         // line 4449
  6603.         echo "\t\t\t\t    </button>
  6604. \t\t\t\t    <a href=\"";
  6605.         // line 4450
  6606.         echo $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getUrl("homepage");
  6607.         echo "\" class=\"sp-bar__home-btn\" title=\"トップページへ\">
  6608. \t\t\t\t        <i class=\"fas fa-home\"></i>
  6609. \t\t\t\t    </a>
  6610. \t\t\t\t</div>
  6611. \t\t\t\t";
  6612.         // line 4456
  6613.         echo "\t\t\t\t";
  6614.         // line 4458
  6615.         echo "\t\t\t\t<div id=\"sp-mitsumori-detail\" class=\"sp-detail-sheet\" aria-hidden=\"true\">
  6616. \t\t\t\t    <div class=\"sp-detail-sheet__overlay\" onclick=\"closeSpMitsumoriDetail();\"></div>
  6617. \t\t\t\t    <div class=\"sp-detail-sheet__panel\" role=\"dialog\" aria-label=\"お見積りの詳細\">
  6618. \t\t\t\t        <div class=\"sp-detail-sheet__header\">
  6619. \t\t\t\t            <span class=\"sp-detail-sheet__title\">お見積りの詳細</span>
  6620. \t\t\t\t            <button type=\"button\" class=\"sp-detail-sheet__close\" onclick=\"closeSpMitsumoriDetail();\" aria-label=\"閉じる\">&times;</button>
  6621. \t\t\t\t        </div>
  6622. \t\t\t\t        <div class=\"sp-detail-sheet__body\" id=\"sp-detail-body\"></div>
  6623. \t\t\t\t        <div class=\"sp-detail-sheet__footer\">
  6624. \t\t\t\t            <button type=\"button\" class=\"sp-detail-sheet__invoice\"
  6625. \t\t\t\t                    onclick=\"closeSpMitsumoriDetail(); document.getElementById('mitsumori_btn') && document.getElementById('mitsumori_btn').click();\">見積書を表示</button>
  6626. \t\t\t\t            <button type=\"button\" class=\"sp-detail-sheet__cart\"
  6627. \t\t\t\t                    onclick=\"closeSpMitsumoriDetail(); document.getElementById('cart_btn2') && document.getElementById('cart_btn2').click();\">カートに入れる</button>
  6628. \t\t\t\t        </div>
  6629. \t\t\t\t    </div>
  6630. \t\t\t\t</div>
  6631. \t\t\t\t";
  6632.         // line 4476
  6633.         echo "\t\t\t\t<div id=\"tg-options\" class=\"tg-options-container col-12\"></div>
  6634. \t\t\t\t<div class=\"card col-12 collapsed-card sticky-top float-right mitsumori-card-pc\">
  6635. \t\t\t\t\t<div class=\"card-header\">
  6636. \t\t\t\t\t  <h3 class=\"card-title\">現在のお見積り額</h3>
  6637. \t\t\t\t\t  <div class=\"card-tools\">
  6638. \t\t\t\t\t    <span class=\"float-left\" id=\"mitsumori_message\">395000円</span>
  6639. \t\t\t\t\t    <button type=\"button\" class=\"btn btn-tool btn-mitsumori-toggle\" data-card-widget=\"collapse\" title=\"詳細を表示\">
  6640. \t\t\t\t\t      <span class=\"toggle-icon\">▼ 詳細</span>
  6641. \t\t\t\t\t    </button>
  6642. \t\t\t\t\t  </div>
  6643. \t\t\t\t\t</div>
  6644. \t\t\t\t\t<div class=\"card-body p-0\">
  6645. \t\t\t\t\t  <ul class=\"nav nav-pills flex-column\">
  6646. \t\t\t\t\t    <li class=\"nav-item active\">
  6647. \t\t\t\t\t      <a class=\"nav-link\">
  6648. \t\t\t\t\t        <i class=\"far fa-file-alt\"></i> 合計(工事費・税込)
  6649. \t\t\t\t\t        <span class=\"float-right\" id=\"mitsumori_goukei\">395,000円</span>
  6650. \t\t\t\t\t      </a>
  6651. \t\t\t\t\t    </li>
  6652. \t\t\t\t\t    <li class=\"nav-item active\">
  6653. \t\t\t\t\t      <a class=\"nav-link\">
  6654. \t\t\t\t\t        <i class=\"far fa-file-alt\"></i> 商品価格
  6655. \t\t\t\t\t        <span class=\"float-right\" id=\"mitsumori_price\">307,008円</span>
  6656. \t\t\t\t\t      </a>
  6657. \t\t\t\t\t    </li>
  6658. \t\t\t\t\t    ";
  6659.         // line 4503
  6660.         echo "\t\t\t\t\t    ";
  6661.         if ((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'4503$this->source); })()), "SaleType", [], "any"falsefalsefalse4503), "id", [], "any"falsefalsefalse4503) != 2)) {
  6662.             // line 4504
  6663.             echo "\t\t\t\t\t    <li class=\"nav-item\">
  6664. \t\t\t\t\t      <a class=\"nav-link\">
  6665. \t\t\t\t\t        &nbsp;&nbsp;<i class=\"far fa-file-alt\"></i> カタログ価格
  6666. \t\t\t\t\t        <span class=\"float-right\" id=\"maker_price\">479,700円</span>
  6667. \t\t\t\t\t      </a>
  6668. \t\t\t\t\t    </li>
  6669. \t\t\t\t\t    ";
  6670.         } else {
  6671.             // line 4511
  6672.             echo "\t\t\t\t\t    ";
  6673.             // line 4512
  6674.             echo "\t\t\t\t\t    <span id=\"maker_price\" style=\"display:none;\">---円</span>
  6675. \t\t\t\t\t    ";
  6676.         }
  6677.         // line 4514
  6678.         echo "\t\t\t\t\t    <li class=\"nav-item\">
  6679. \t\t\t\t\t      <a class=\"nav-link\">
  6680. \t\t\t\t\t        &nbsp;&nbsp;<i class=\"far fa-file-alt\"></i>
  6681. \t\t\t\t\t        ";
  6682.         // line 4517
  6683.         if ((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'4517$this->source); })()), "SaleType", [], "any"falsefalsefalse4517), "id", [], "any"falsefalsefalse4517) == 2)) {
  6684.             echo "補助金(割引額)";
  6685.         } else {
  6686.             echo "お値引き";
  6687.         }
  6688.         // line 4518
  6689.         echo "\t\t\t\t\t        <span class=\"float-right\" id=\"mitsumori_off\">-172,692円</span>
  6690. \t\t\t\t\t      </a>
  6691. \t\t\t\t\t    </li>
  6692. \t\t\t\t\t    ";
  6693.         // line 4522
  6694.         echo "\t\t\t\t\t    ";
  6695.         if ((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'4522$this->source); })()), "SaleType", [], "any"falsefalsefalse4522), "id", [], "any"falsefalsefalse4522) == 2)) {
  6696.             // line 4523
  6697.             echo "\t\t\t\t\t    <li class=\"nav-item\">
  6698. \t\t\t\t\t      <div style=\"padding:4px 12px 8px;color:#6c757d;font-size:11px;line-height:1.4;\">
  6699. \t\t\t\t\t        ※当店が補助金事業者として申請代行し、契約代金に充当します
  6700. \t\t\t\t\t      </div>
  6701. \t\t\t\t\t    </li>
  6702. \t\t\t\t\t    ";
  6703.         }
  6704.         // line 4529
  6705.         echo "\t\t\t\t\t    <li class=\"nav-item\">
  6706. \t\t\t\t\t      <a class=\"nav-link\">
  6707. \t\t\t\t\t        <i class=\"far fa-file-alt\"></i> 基本工事費
  6708. \t\t\t\t\t        <span class=\"float-right\" id=\"mitsumori_ct\">53,250円</span>
  6709. \t\t\t\t\t      </a>
  6710. \t\t\t\t\t    </li>
  6711. \t\t\t\t\t    <li class=\"nav-item\">
  6712. \t\t\t\t\t      <a class=\"nav-link\">
  6713. \t\t\t\t\t        <i class=\"far fa-file-alt\"></i> 施工オプション
  6714. \t\t\t\t\t        <span class=\"float-right\"id=\"mitsumori_option\">6,297円</span>
  6715. \t\t\t\t\t      </a>
  6716. \t\t\t\t\t    </li>
  6717. \t\t\t\t\t  </ul>
  6718. \t\t\t\t\t</div>
  6719. \t\t\t\t\t<div class=\"card-footer\">
  6720. \t\t                <button type=\"button\" id=\"mitsumori_btn\" class=\"btn btn-info\" data-toggle=\"modal\" data-target=\"#modal-mitsumori\">
  6721. \t\t                  見積書表示
  6722. \t\t                </button>
  6723.                         <button type=\"submit\" id=\"cart_btn2\" class=\"btn btn-info add-cart\">カートに入れる</button>
  6724. \t\t\t\t\t</div>
  6725. \t\t\t\t</div>
  6726.             </div>
  6727.         </div>
  6728.     </div>
  6729.   <div class=\"modal\" id=\"modal-mitsumori\">
  6730.     <div class=\"modal-dialog modal-mitsumori\" style=\"max-width:1000px\">
  6731.       <div class=\"modal-content\">
  6732.         <div class=\"modal-header\">
  6733.           <h4 class=\"modal-title\">お見積書</h4>
  6734.           <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Close\">
  6735.             <span aria-hidden=\"true\">&times;</span>
  6736.           </button>
  6737.         </div>
  6738.         <div class=\"modal-body\">
  6739. \t\t\t<div class=\"invoice p-3 mb-5\" style=\"max-width:1000px; margin:auto;\">
  6740. \t\t\t  <!-- title row -->
  6741. \t\t\t  <div class=\"row\">
  6742. \t\t\t    <div class=\"col-12\">
  6743. \t\t\t      <h2>概算お見積書 
  6744. \t\t\t        <small class=\"float-right\" style=\"font-size:14px;\">発行日: 2025/03/14</small>
  6745. \t\t\t      </h2>
  6746. \t\t\t    </div>
  6747. \t\t\t    <!-- /.col -->
  6748. \t\t\t  </div>
  6749. \t\t\t  <!-- info row -->
  6750. \t\t\t  <div class=\"row invoice-info\">
  6751. \t\t\t    <div class=\"col-sm-8 invoice-col\">
  6752. \t\t\t      <h3>お客様</h3>
  6753. \t\t\t      <span>下記の通り、お見積もり申し上げます。</span>
  6754. \t\t\t      <br />
  6755. \t\t\t      <br / >
  6756. \t\t\t      <br />
  6757. \t\t\t      <h2>お見積金額: <span id=\"mitsumori_kei\">399,080円</span></h2>
  6758. \t\t\t      <span>
  6759. \t\t\t        <br/>
  6760. \t\t\t        <br/>
  6761. \t\t\t        <br/>
  6762. \t\t\t        <br/>
  6763. \t\t\t      </span>
  6764. \t\t\t    </div>
  6765. \t\t\t    <div class=\"col-sm-4 invoice-col\">
  6766. \t\t\t      <p>
  6767. \t\t\t        <img alt=\"\" src=\"/html/user_data/js/images/logo.png\" style=\"width: 260px; max-width: 100%; max-height: 10mm;\">
  6768. \t\t\t      </p>
  6769. \t\t\t      <p>有限会社プラス</p>
  6770. \t\t\t      <p>〒400-0334</p>
  6771. \t\t\t      <p>山梨県南アルプス市藤田1450番地2</p>
  6772. \t\t\t      <p>TEL: 055-284-6480</p>
  6773. \t\t\t      <img alt=\"\" src=\"/html/user_data/js/images/seal.svg\" style=\"z-index: 2; position: absolute; width: 21mm; left: 58mm; top: 36mm;\">
  6774. \t\t\t    </div>
  6775. \t\t\t    <!-- /.col -->
  6776. \t\t\t    <!-- /.col -->
  6777. \t\t\t  </div>
  6778. \t\t\t  <!-- /.row -->
  6779. \t\t\t  <!-- Table row -->
  6780. \t\t\t  <div class=\"row\">
  6781. \t\t\t    <div class=\"col-12 table-responsive\">
  6782. \t\t\t      <table class=\"table table-striped\">
  6783. \t\t\t        <thead>
  6784. \t\t\t          <tr>
  6785. \t\t\t            <th>項目</th>
  6786. \t\t\t            <th>数量</th>
  6787. \t\t\t            <th>単位</th>
  6788. \t\t\t            <th>単価</th>
  6789. \t\t\t            <th>小計</th>
  6790. \t\t\t          </tr>
  6791. \t\t\t        </thead>
  6792. \t\t\t        <tbody>
  6793. \t\t\t          <tr>
  6794. \t\t\t            <td id=\"mitsumori_item_name\">";
  6795.         // line 4622
  6796.         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'4622$this->source); })()), "name", [], "any"falsefalsefalse4622), "html"nulltrue);
  6797.         echo "</td>
  6798. \t\t\t            <td>1</td>
  6799. \t\t\t            <td>式</td>
  6800. \t\t\t            <td id=\"mitsumori_price_01\">352,800</td>
  6801. \t\t\t            <td id=\"mitsumori_price_02\">352,800</td>
  6802. \t\t\t          </tr>
  6803. \t\t\t          <tr>
  6804. \t\t\t            <td>基本工事費</td>
  6805. \t\t\t            <td>1</td>
  6806. \t\t\t            <td>式</td>
  6807. \t\t\t            <td id=\"mitsumori_ct_01\">10,000</td>
  6808. \t\t\t            <td id=\"mitsumori_ct_02\">10,000</td>
  6809. \t\t\t          </tr>
  6810. \t\t\t          <tr>
  6811. \t\t\t            <td>残土・ガラ処理</td>
  6812. \t\t\t            <td>1</td>
  6813. \t\t\t            <td>式</td>
  6814. \t\t\t            <td>0円</td>
  6815. \t\t\t            <td></td>
  6816. \t\t\t          </tr>
  6817. \t\t\t          <tr>
  6818. \t\t\t            <td> </td>
  6819. \t\t\t            <td></td>
  6820. \t\t\t            <td></td>
  6821. \t\t\t            <td></td>
  6822. \t\t\t            <td></td>
  6823. \t\t\t          </tr>
  6824. \t\t\t        </tbody>
  6825. \t\t\t      </table>
  6826. \t\t\t    </div>
  6827. \t\t\t    <!-- /.col -->
  6828. \t\t\t  </div>
  6829. \t\t\t  <!-- /.row -->
  6830. \t\t\t  <div class=\"row\">
  6831. \t\t\t    <!-- accepted payments column -->
  6832. \t\t\t    <div class=\"col-6\">
  6833. \t\t\t      <p class=\"lead\">お支払い方法</p>
  6834. \t\t\t      <p class=\"text-muted well well-sm shadow-none\" style=\"margin-top: 10px;\">銀行振込、クレジットカード決済、PAYPAY決済
  6835. \t\t\t        <br>銀行振込:山梨中央銀行 白根支店 普通口座 391402
  6836. \t\t\t        <br>※商品代金と工事代金の総額が金100万円(税込)を超える場合、着手金として代金の半額をご契約後お支払いいただきます。 
  6837. \t\t\t      </p>
  6838. \t\t\t    </div>
  6839. \t\t\t    <!-- /.col -->
  6840. \t\t\t    <div class=\"col-6\">
  6841. \t\t\t      <div class=\"table-responsive\">
  6842. \t\t\t        <table class=\"table\">
  6843. \t\t\t          <tbody>
  6844. \t\t\t            <tr>
  6845. \t\t\t              <th style=\"width:50%\">小計:</th>
  6846. \t\t\t              <td id=\"mitsumori_shoukei\">362,800</td>
  6847. \t\t\t            </tr>
  6848. \t\t\t            <tr>
  6849. \t\t\t              <th>消費税 (10%)</th>
  6850. \t\t\t              <td id=\"mitsumori_tax\">36,280</td>
  6851. \t\t\t            </tr>
  6852. \t\t\t            <tr>
  6853. \t\t\t              <th>合計:</th>
  6854. \t\t\t              <td id=\"mitsumori_goukei_02\">399,080</td>
  6855. \t\t\t            </tr>
  6856. \t\t\t          </tbody>
  6857. \t\t\t        </table>
  6858. \t\t\t      </div>
  6859. \t\t\t    </div>
  6860. \t\t\t    <!-- /.col -->
  6861. \t\t\t  </div>
  6862. \t\t\t  <!-- /.row -->
  6863. \t\t\t</div>
  6864.         </div>
  6865.         <div class=\"modal-footer justify-content-between\">
  6866. \t\t\t      ";
  6867.         // line 4692
  6868.         echo "\t\t\t      <form method=\"post\" action=\"";
  6869.         echo $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getUrl("mitsumori_pdf");
  6870.         echo "\" target=\"_blank\" id=\"pdf_download_form\">
  6871. \t\t\t        <input type=\"hidden\" name=\"_token\" value=\"";
  6872.         // line 4693
  6873.         echo twig_escape_filter($this->env$this->env->getRuntime('Symfony\Component\Form\FormRenderer')->renderCsrfToken("mitsumori_pdf"), "html"nulltrue);
  6874.         echo "\">
  6875. \t\t\t        <input type=\"hidden\" name=\"mitsumori_json\" id=\"pdf_mitsumori_json\">
  6876. \t\t\t        <button type=\"submit\" class=\"btn btn-primary float-right\" style=\"margin-right: 5px;\" onclick=\"syncPdfJson();\">
  6877. \t\t\t          <i class=\"fas fa-download\"></i>PDF出力
  6878. \t\t\t        </button>
  6879. \t\t\t      </form>
  6880.                   <button type=\"submit\" id=\"cart_btn3\" class=\"btn btn-info add-cart\">カートに入れる</button>
  6881.         </div>
  6882.       </div>
  6883.       <!-- /.modal-content -->
  6884.     </div>
  6885.     <!-- /.modal-dialog -->
  6886.   </div>
  6887.   <!-- /.modal -->
  6888.     <!-- Image zoom modal: custom lightweight lightbox (no CDN dependency) -->
  6889.     <div id=\"img-modal\" role=\"dialog\" aria-modal=\"true\" aria-label=\"画像拡大\">
  6890.         <button id=\"img-modal__close\" aria-label=\"閉じる\">&times;</button>
  6891.         <button id=\"img-modal__prev\" aria-label=\"前の画像\">&#10094;</button>
  6892.         <img id=\"img-modal__img\" src=\"\" alt=\"\">
  6893.         <button id=\"img-modal__next\" aria-label=\"次の画像\">&#10095;</button>
  6894.     </div>
  6895.     <style>
  6896.     #img-modal {
  6897.         display: none;
  6898.         position: fixed;
  6899.         inset: 0;
  6900.         z-index: 9999;
  6901.         background: rgba(0,0,0,0.88);
  6902.         align-items: center;
  6903.         justify-content: center;
  6904.         cursor: zoom-out;
  6905.     }
  6906.     #img-modal.is-open { display: flex; }
  6907.     #img-modal__img {
  6908.         max-width: 92vw;
  6909.         max-height: 88vh;
  6910.         object-fit: contain;
  6911.         border-radius: 4px;
  6912.         cursor: default;
  6913.         user-select: none;
  6914.         touch-action: pinch-zoom;
  6915.         display: block;
  6916.     }
  6917.     #img-modal__close {
  6918.         position: absolute;
  6919.         top: 14px;
  6920.         right: 18px;
  6921.         font-size: 38px;
  6922.         color: #fff;
  6923.         cursor: pointer;
  6924.         background: none;
  6925.         border: none;
  6926.         padding: 0;
  6927.         line-height: 1;
  6928.         z-index: 1;
  6929.         opacity: 0.85;
  6930.     }
  6931.     #img-modal__close:hover { opacity: 1; }
  6932.     #img-modal__prev,
  6933.     #img-modal__next {
  6934.         position: absolute;
  6935.         top: 50%;
  6936.         transform: translateY(-50%);
  6937.         font-size: 36px;
  6938.         color: #fff;
  6939.         cursor: pointer;
  6940.         background: rgba(0,0,0,0.32);
  6941.         border: none;
  6942.         padding: 10px 16px;
  6943.         line-height: 1;
  6944.         border-radius: 6px;
  6945.         z-index: 1;
  6946.         opacity: 0.8;
  6947.         user-select: none;
  6948.     }
  6949.     #img-modal__prev:hover, #img-modal__next:hover { opacity: 1; }
  6950.     #img-modal__prev { left: 12px; }
  6951.     #img-modal__next { right: 12px; }
  6952.     @media (max-width: 767px) {
  6953.         #img-modal__prev, #img-modal__next { font-size: 28px; padding: 8px 12px; }
  6954.     }
  6955.     </style>
  6956.     <script>
  6957.     (function(){
  6958.         var images = [];
  6959.         var current = 0;
  6960.         // Collect original (non-cloned) slide images at click time.
  6961.         // After Slick init, slides are wrapped in .slick-slide; clones have .slick-cloned.
  6962.         function collectImages() {
  6963.             images = [];
  6964.             var \$slides = \$('.item_visual .slick-slide:not(.slick-cloned)');
  6965.             if (!\$slides.length) {
  6966.                 // Slick not yet initialized (fallback)
  6967.                 \$slides = \$('.item_visual .slide-item');
  6968.             }
  6969.             \$slides.each(function() {
  6970.                 var \$a = \$(this).find('a.js-zoom');
  6971.                 if (\$a.length) {
  6972.                     images.push({ src: \$a.attr('href'), alt: \$a.find('img').attr('alt') || '' });
  6973.                 }
  6974.             });
  6975.         }
  6976.         function showImage(idx) {
  6977.             current = ((idx % images.length) + images.length) % images.length;
  6978.             \$('#img-modal__img').attr({ src: images[current].src, alt: images[current].alt });
  6979.         }
  6980.         function openModal(href) {
  6981.             collectImages();
  6982.             if (!images.length) return;
  6983.             var idx = 0;
  6984.             for (var i = 0; i < images.length; i++) {
  6985.                 if (images[i].src === href) { idx = i; break; }
  6986.             }
  6987.             showImage(idx);
  6988.             \$('#img-modal').addClass('is-open');
  6989.             \$('body').css('overflow', 'hidden');
  6990.         }
  6991.         function closeModal() {
  6992.             \$('#img-modal').removeClass('is-open');
  6993.             \$('body').css('overflow', '');
  6994.         }
  6995.         // Click handler: works for both original and Slick-cloned anchors
  6996.         \$(document).on('click', '.item_visual a.js-zoom', function(e) {
  6997.             e.preventDefault();
  6998.             openModal(\$(this).attr('href'));
  6999.         });
  7000.         // Close on backdrop click
  7001.         \$('#img-modal').on('click', function(e) {
  7002.             if (e.target === this) closeModal();
  7003.         });
  7004.         \$('#img-modal__close').on('click', closeModal);
  7005.         \$('#img-modal__prev').on('click', function(e) { e.stopPropagation(); showImage(current - 1); });
  7006.         \$('#img-modal__next').on('click', function(e) { e.stopPropagation(); showImage(current + 1); });
  7007.         // Keyboard navigation
  7008.         \$(document).on('keydown', function(e) {
  7009.             if (!\$('#img-modal').hasClass('is-open')) return;
  7010.             if (e.key === 'Escape') closeModal();
  7011.             if (e.key === 'ArrowLeft') showImage(current - 1);
  7012.             if (e.key === 'ArrowRight') showImage(current + 1);
  7013.         });
  7014.         // Touch swipe (horizontal only)
  7015.         var _tx = 0;
  7016.         var \$modal = document.getElementById('img-modal');
  7017.         \$modal.addEventListener('touchstart', function(e) {
  7018.             _tx = e.changedTouches[0].clientX;
  7019.         }, { passive: true });
  7020.         \$modal.addEventListener('touchend', function(e) {
  7021.             var dx = e.changedTouches[0].clientX - _tx;
  7022.             if (Math.abs(dx) > 48) {
  7023.                 dx < 0 ? showImage(current + 1) : showImage(current - 1);
  7024.             }
  7025.         }, { passive: true });
  7026.     })();
  7027.     </script>
  7028. ";
  7029.         
  7030.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->leave($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof);
  7031.         
  7032.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->leave($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof);
  7033.     }
  7034.     public function getTemplateName()
  7035.     {
  7036.         return "Product/detail.twig";
  7037.     }
  7038.     public function isTraitable()
  7039.     {
  7040.         return false;
  7041.     }
  7042.     public function getDebugInfo()
  7043.     {
  7044.         return array (  7123 => 4693,  7118 => 4692,  7046 => 4622,  6951 => 4529,  6943 => 4523,  6940 => 4522,  6935 => 4518,  6929 => 4517,  6924 => 4514,  6920 => 4512,  6918 => 4511,  6909 => 4504,  6906 => 4503,  6878 => 4476,  6859 => 4458,  6857 => 4456,  6849 => 4450,  6846 => 4449,  6840 => 4447,  6837 => 4446,  6835 => 4445,  6819 => 4431,  6809 => 4423,  6801 => 4418,  6791 => 4413,  6786 => 4410,  6780 => 4406,  6771 => 4400,  6765 => 4399,  6759 => 4396,  6755 => 4395,  6747 => 4390,  6742 => 4387,  6735 => 4383,  6731 => 4381,  6723 => 4376,  6719 => 4375,  6716 => 4374,  6713 => 4373,  6707 => 4370,  6703 => 4369,  6700 => 4368,  6698 => 4367,  6693 => 4365,  6689 => 4364,  6686 => 4363,  6684 => 4362,  6681 => 4361,  6679 => 4360,  6675 => 4359,  6667 => 4353,  6663 => 4351,  6660 => 4350,  6657 => 4346,  6651 => 4345,  6648 => 4344,  6645 => 4343,  6641 => 4341,  6629 => 4337,  6627 => 4336,  6624 => 4335,  6618 => 4332,  6606 => 4331,  6600 => 4330,  6593 => 4329,  6591 => 4328,  6586 => 4326,  6574 => 4325,  6568 => 4324,  6561 => 4323,  6558 => 4320,  6552 => 4319,  6543 => 4318,  6535 => 4316,  6532 => 4315,  6530 => 4314,  6528 => 4313,  6526 => 4312,  6524 => 4310,  6521 => 4309,  6518 => 4308,  6515 => 4307,  6512 => 4306,  6509 => 4305,  6506 => 4304,  6503 => 4303,  6500 => 4302,  6497 => 4301,  6494 => 4300,  6489 => 4299,  6486 => 4298,  6480 => 4297,  6475 => 4296,  6470 => 4295,  6465 => 4294,  6462 => 4293,  6459 => 4292,  6456 => 4291,  6449 => 4283,  6433 => 4269,  6431 => 4268,  6427 => 4266,  6413 => 4255,  6406 => 4250,  6404 => 4249,  6402 => 4248,  6398 => 4246,  6386 => 4237,  6382 => 4235,  6377 => 4232,  6369 => 4226,  6360 => 4220,  6352 => 4214,  6349 => 4211,  6338 => 4208,  6335 => 4207,  6332 => 4206,  6329 => 4205,  6326 => 4203,  6321 => 4200,  6311 => 4197,  6305 => 4196,  6299 => 4195,  6295 => 4194,  6288 => 4193,  6281 => 4192,  6279 => 4191,  6270 => 4189,  6267 => 4188,  6264 => 4187,  6261 => 4184,  6256 => 4181,  6246 => 4178,  6240 => 4177,  6234 => 4176,  6230 => 4175,  6223 => 4174,  6216 => 4173,  6214 => 4172,  6205 => 4170,  6202 => 4169,  6199 => 4168,  6196 => 4166,  6194 => 4165,  6190 => 4163,  6179 => 4157,  6170 => 4153,  6162 => 4150,  6154 => 4147,  6145 => 4144,  6142 => 4143,  6140 => 4142,  6135 => 4139,  6125 => 4133,  6116 => 4129,  6108 => 4126,  6100 => 4123,  6091 => 4120,  6088 => 4119,  6086 => 4118,  6081 => 4115,  6078 => 4113,  6076 => 4112,  6072 => 4110,  6058 => 4099,  6052 => 4095,  6049 => 4093,  6047 => 4092,  6043 => 4090,  6029 => 4079,  6023 => 4075,  6020 => 4073,  6015 => 4070,  6005 => 4067,  5999 => 4066,  5993 => 4065,  5989 => 4064,  5982 => 4063,  5975 => 4062,  5973 => 4061,  5964 => 4059,  5961 => 4058,  5958 => 4057,  5955 => 4055,  5950 => 4052,  5940 => 4049,  5934 => 4048,  5928 => 4047,  5924 => 4046,  5917 => 4045,  5910 => 4044,  5908 => 4043,  5898 => 4041,  5895 => 4040,  5892 => 4039,  5889 => 4037,  5884 => 4034,  5874 => 4031,  5868 => 4030,  5862 => 4029,  5858 => 4028,  5851 => 4027,  5844 => 4026,  5842 => 4025,  5833 => 4023,  5830 => 4022,  5827 => 4021,  5824 => 4019,  5819 => 4016,  5809 => 4013,  5803 => 4012,  5797 => 4011,  5793 => 4010,  5786 => 4009,  5779 => 4008,  5777 => 4007,  5768 => 4005,  5765 => 4004,  5763 => 4003,  5760 => 4002,  5755 => 3999,  5745 => 3996,  5739 => 3995,  5733 => 3994,  5729 => 3993,  5722 => 3992,  5715 => 3991,  5713 => 3990,  5704 => 3988,  5701 => 3987,  5699 => 3986,  5696 => 3985,  5691 => 3982,  5681 => 3979,  5675 => 3978,  5669 => 3977,  5665 => 3976,  5658 => 3975,  5651 => 3974,  5649 => 3973,  5640 => 3971,  5637 => 3970,  5634 => 3969,  5631 => 3967,  5629 => 3966,  5625 => 3964,  5495 => 3836,  5478 => 3820,  5475 => 3818,  5470 => 3815,  5462 => 3813,  5456 => 3811,  5451 => 3809,  5443 => 3807,  5441 => 3806,  5437 => 3805,  5430 => 3804,  5427 => 3803,  5422 => 3802,  5417 => 3799,  5414 => 3798,  5411 => 3796,  5405 => 3792,  5395 => 3789,  5391 => 3788,  5388 => 3787,  5383 => 3786,  5378 => 3783,  5375 => 3782,  5372 => 3780,  5364 => 3777,  5354 => 3769,  5351 => 3768,  5348 => 3766,  5340 => 3763,  5330 => 3755,  5327 => 3754,  5324 => 3752,  5319 => 3749,  5309 => 3746,  5305 => 3745,  5302 => 3744,  5297 => 3743,  5292 => 3740,  5289 => 3739,  5280 => 3731,  5255 => 3710,  5245 => 3705,  5234 => 3696,  5231 => 3695,  5221 => 3686,  5218 => 3682,  5215 => 3678,  5213 => 3677,  5209 => 3675,  5206 => 3674,  5204 => 3673,  5200 => 3671,  5195 => 3668,  5185 => 3665,  5179 => 3664,  5173 => 3663,  5169 => 3662,  5162 => 3661,  5155 => 3660,  5153 => 3659,  5143 => 3657,  5140 => 3656,  5137 => 3655,  5134 => 3653,  5129 => 3650,  5119 => 3647,  5113 => 3646,  5107 => 3645,  5103 => 3644,  5096 => 3643,  5089 => 3642,  5087 => 3641,  5077 => 3639,  5074 => 3638,  5071 => 3637,  5068 => 3632,  5063 => 3629,  5053 => 3626,  5047 => 3625,  5041 => 3624,  5037 => 3623,  5030 => 3622,  5023 => 3621,  5021 => 3620,  5007 => 3618,  5004 => 3617,  5001 => 3616,  4998 => 3614,  4993 => 3611,  4983 => 3608,  4977 => 3607,  4971 => 3606,  4967 => 3605,  4960 => 3604,  4953 => 3603,  4951 => 3602,  4942 => 3600,  4939 => 3599,  4936 => 3598,  4933 => 3595,  4928 => 3592,  4918 => 3589,  4912 => 3588,  4906 => 3587,  4902 => 3586,  4895 => 3585,  4888 => 3584,  4886 => 3583,  4877 => 3581,  4874 => 3580,  4872 => 3579,  4869 => 3578,  4864 => 3575,  4854 => 3572,  4848 => 3571,  4842 => 3570,  4838 => 3569,  4831 => 3568,  4824 => 3567,  4822 => 3566,  4813 => 3564,  4810 => 3563,  4807 => 3562,  4804 => 3557,  4799 => 3554,  4791 => 3552,  4785 => 3550,  4780 => 3548,  4772 => 3546,  4770 => 3545,  4764 => 3544,  4758 => 3543,  4754 => 3542,  4744 => 3541,  4741 => 3540,  4734 => 3539,  4732 => 3538,  4723 => 3536,  4720 => 3535,  4717 => 3534,  4714 => 3532,  4710 => 3530,  4707 => 3529,  4705 => 3527,  4704 => 3526,  4703 => 3525,  4702 => 3524,  4701 => 3523,  4700 => 3522,  4699 => 3521,  4698 => 3520,  4696 => 3519,  4693 => 3518,  4687 => 3517,  4684 => 3516,  4679 => 3515,  4674 => 3514,  4669 => 3513,  4666 => 3512,  4663 => 3511,  4658 => 3510,  4655 => 3509,  4652 => 3508,  4649 => 3507,  4643 => 3506,  4638 => 3505,  4633 => 3504,  4628 => 3503,  4625 => 3502,  4622 => 3501,  4619 => 3500,  4615 => 3491,  4611 => 3489,  4607 => 3487,  4598 => 3484,  4589 => 3483,  4585 => 3482,  4582 => 3481,  4580 => 3480,  4576 => 3478,  4567 => 3475,  4563 => 3474,  4559 => 3473,  4549 => 3471,  4545 => 3470,  4542 => 3469,  4540 => 3468,  4538 => 3467,  4529 => 3466,  4526 => 3465,  4523 => 3464,  4520 => 3462,  4516 => 3460,  4512 => 3458,  4503 => 3455,  4494 => 3454,  4490 => 3453,  4487 => 3452,  4483 => 3450,  4474 => 3447,  4467 => 3443,  4463 => 3442,  4453 => 3440,  4449 => 3439,  4446 => 3438,  4444 => 3437,  4435 => 3436,  4432 => 3435,  4429 => 3434,  4426 => 3432,  4422 => 3430,  4418 => 3428,  4409 => 3425,  4400 => 3424,  4396 => 3423,  4393 => 3422,  4389 => 3420,  4380 => 3417,  4373 => 3413,  4369 => 3412,  4359 => 3410,  4355 => 3409,  4352 => 3408,  4350 => 3407,  4341 => 3406,  4338 => 3405,  4335 => 3404,  4332 => 3402,  4328 => 3400,  4324 => 3398,  4315 => 3395,  4306 => 3394,  4302 => 3393,  4299 => 3392,  4297 => 3391,  4293 => 3389,  4284 => 3386,  4277 => 3382,  4273 => 3381,  4263 => 3379,  4259 => 3378,  4256 => 3377,  4254 => 3376,  4252 => 3375,  4243 => 3374,  4240 => 3373,  4237 => 3372,  4234 => 3370,  4230 => 3368,  4227 => 3367,  4225 => 3366,  4224 => 3365,  4223 => 3364,  4221 => 3363,  4218 => 3362,  4215 => 3361,  4212 => 3360,  4209 => 3359,  4206 => 3358,  4203 => 3357,  4200 => 3356,  4197 => 3355,  4195 => 3354,  4193 => 3353,  4181 => 3344,  4174 => 3339,  4162 => 3336,  4159 => 3335,  4156 => 3334,  4153 => 3332,  4142 => 3330,  4138 => 3329,  4135 => 3328,  4132 => 3326,  4126 => 3323,  4122 => 3322,  4119 => 3321,  4116 => 3320,  4110 => 3317,  4104 => 3316,  4101 => 3315,  4095 => 3312,  4091 => 3311,  4088 => 3310,  4086 => 3309,  4084 => 3308,  4080 => 3306,  4078 => 3305,  4074 => 3303,  4068 => 3302,  4063 => 3299,  4048 => 3297,  4039 => 3296,  4022 => 3295,  4018 => 3293,  4015 => 3292,  4011 => 3291,  4008 => 3290,  4005 => 3289,  4002 => 3288,  3989 => 3277,  3975 => 3265,  3969 => 3260,  3950 => 3258,  3933 => 3257,  3929 => 3255,  3918 => 3253,  3895 => 3249,  3889 => 3248,  3886 => 3247,  3868 => 3246,  3865 => 3245,  3861 => 3243,  3853 => 3239,  3845 => 3235,  3843 => 3234,  3840 => 3233,  3838 => 3232,  3828 => 3225,  3816 => 3218,  3811 => 3216,  3807 => 3214,  3801 => 3209,  3798 => 3208,  3792 => 3207,  3787 => 3206,  3782 => 3205,  3775 => 3204,  3769 => 3203,  3764 => 3202,  3761 => 3201,  3758 => 3200,  3756 => 3197,  3753 => 3196,  3750 => 3195,  3748 => 3194,  3738 => 3193,  3722 => 3186,  3718 => 3185,  3714 => 3184,  3710 => 3183,  3706 => 3181,  3700 => 3179,  3698 => 3178,  3693 => 3177,  3690 => 3176,  3680 => 3174,  3666 => 3172,  3658 => 3171,  3640 => 3170,  3635 => 3168,  3505 => 3045,  3497 => 3044,  3433 => 2983,  3333 => 2886,  3329 => 2885,  3313 => 2872,  3145 => 2706,  3142 => 2705,  3129 => 2704,  3126 => 2703,  3124 => 2702,  3121 => 2701,  3118 => 2700,  3105 => 2699,  3102 => 2698,  3099 => 2697,  3096 => 2695,  3093 => 2694,  3080 => 2693,  3077 => 2692,  3075 => 2691,  3072 => 2690,  3069 => 2689,  3056 => 2688,  3053 => 2687,  3051 => 2686,  3048 => 2685,  3045 => 2684,  3032 => 2683,  3029 => 2682,  3027 => 2681,  3024 => 2680,  3021 => 2679,  3008 => 2678,  3005 => 2677,  3003 => 2676,  3000 => 2675,  2997 => 2674,  2984 => 2673,  2981 => 2672,  2978 => 2671,  2975 => 2670,  2961 => 2669,  2958 => 2668,  2945 => 2667,  2942 => 2666,  2939 => 2665,  2846 => 2571,  2426 => 2154,  2069 => 1800,  2038 => 1772,  2025 => 1762,  1996 => 1736,  1992 => 1735,  1984 => 1730,  1535 => 1283,  1532 => 1282,  1526 => 1281,  1521 => 1280,  1516 => 1279,  1510 => 1278,  1504 => 1277,  1499 => 1276,  1496 => 1275,  1493 => 1274,  1490 => 1273,  1485 => 1270,  1472 => 1260,  1458 => 1249,  1430 => 1226,  1424 => 1225,  1418 => 1224,  1412 => 1223,  1406 => 1222,  1400 => 1221,  1394 => 1220,  1388 => 1219,  1382 => 1218,  1376 => 1217,  1370 => 1216,  1364 => 1215,  1358 => 1214,  1351 => 1212,  1345 => 1211,  1339 => 1210,  1333 => 1209,  1327 => 1208,  1307 => 1191,  1297 => 1184,  1267 => 1157,  1255 => 1147,  1246 => 1141,  1242 => 1139,  1240 => 1138,  1237 => 1137,  1228 => 1131,  1224 => 1129,  1222 => 1128,  1150 => 1058,  1142 => 1056,  1140 => 1055,  1135 => 1053,  1132 => 1052,  1130 => 1051,  1116 => 1040,  1112 => 1038,  1102 => 1037,  73 => 16,  63 => 15,  52 => 11,  50 => 13,  37 => 11,);
  7045.     }
  7046.     public function getSourceContext()
  7047.     {
  7048.         return new Source("{#
  7049. This file is part of EC-CUBE
  7050. Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
  7051. http://www.ec-cube.co.jp/
  7052. For the full copyright and license information, please view the LICENSE
  7053. file that was distributed with this source code.
  7054. #}
  7055. {% extends 'default_frame.twig' %}
  7056. {% set body_class = 'product_page' %}
  7057. {% block stylesheet %}
  7058.     <style>
  7059.         .slick-slider {
  7060.             margin-bottom: 10px;
  7061. \t\t\tmargin-top: -20px;
  7062.         }
  7063.         .slick-dots {
  7064.             position: absolute;
  7065.             bottom: -45px;
  7066.             display: block;
  7067.             width: 100%;
  7068.             padding: 0;
  7069.             list-style: none;
  7070.             text-align: center;
  7071.         }
  7072.         .slick-dots li {
  7073.             position: relative;
  7074.             display: inline-block;
  7075.             width: 20px;
  7076.             height: 20px;
  7077.             margin: 0 5px;
  7078.             padding: 0;
  7079.             cursor: pointer;
  7080.         }
  7081.         .slick-dots li button {
  7082.             font-size: 0;
  7083.             line-height: 0;
  7084.             display: block;
  7085.             width: 20px;
  7086.             height: 20px;
  7087.             padding: 5px;
  7088.             cursor: pointer;
  7089.             color: transparent;
  7090.             border: 0;
  7091.             outline: none;
  7092.             background: transparent;
  7093.         }
  7094.         .slick-dots li button:hover,
  7095.         .slick-dots li button:focus {
  7096.             outline: none;
  7097.         }
  7098.         .slick-dots li button:hover:before,
  7099.         .slick-dots li button:focus:before {
  7100.             opacity: 1;
  7101.         }
  7102.         .slick-dots li button:before {
  7103.             content: \" \";
  7104.             line-height: 20px;
  7105.             position: absolute;
  7106.             top: 0;
  7107.             left: 0;
  7108.             width: 12px;
  7109.             height: 12px;
  7110.             text-align: center;
  7111.             opacity: .25;
  7112.             background-color: black;
  7113.             border-radius: 50%;
  7114.         }
  7115.         .slick-dots li.slick-active button:before {
  7116.             opacity: .75;
  7117.             background-color: black;
  7118.         }
  7119.         .slick-dots li button.thumbnail img {
  7120.             width: 0;
  7121.             height: 0;
  7122.         }
  7123.     </style>
  7124.     <link rel=\"stylesheet\" href=\"/html/user_data/js/style.css\">
  7125.     <link rel=\"stylesheet\" href=\"/html/plugins/icheck-bootstrap/icheck-bootstrap.min.css\">
  7126.     <style>
  7127.         /* Show zoom cursor on product images to hint click-to-expand */
  7128.         .item_visual .slide-item a { display: block; cursor: zoom-in; }
  7129.     </style>
  7130.     <style>
  7131.         /* ============================================
  7132.            商品詳細グリッド: 画像50% / 内容50%(均等)
  7133.         ============================================ */
  7134.         @media (min-width: 768px) {
  7135.             body.product_page .ec-grid2 {
  7136.                 display: flex;
  7137.                 align-items: flex-start;
  7138.             }
  7139.             body.product_page .ec-grid2 .ec-grid2__cell {
  7140.                 width: 50%;
  7141.                 flex: 0 0 50%;
  7142.                 min-width: 0;
  7143.             }
  7144.             body.product_page .ec-grid2 .ec-grid2__cell2 {
  7145.                 width: 50%;
  7146.                 flex: 0 0 50%;
  7147.                 min-width: 0;
  7148.             }
  7149.         }
  7150.         /* ============================================
  7151.            商品説明欄内のHTMLが画面幅を突き抜けないように
  7152.         ============================================ */
  7153.         body.product_page .ec-productRole__description {
  7154.             min-width: 0;
  7155.             overflow-wrap: break-word;
  7156.             word-break: break-word;
  7157.         }
  7158.         body.product_page .ec-productRole__description img,
  7159.         body.product_page .ec-productRole__description table,
  7160.         body.product_page .ec-productRole__description iframe,
  7161.         body.product_page .ec-productRole__description video {
  7162.             max-width: 100% !important;
  7163.             height: auto;
  7164.         }
  7165.         body.product_page .ec-productRole__description table {
  7166.             display: block;
  7167.             overflow-x: auto;
  7168.             -webkit-overflow-scrolling: touch;
  7169.         }
  7170.         /* ============================================
  7171.            スマホ用 見積金額 下部固定バー
  7172.         ============================================ */
  7173.         #sp-mitsumori-bar {
  7174.             display: none;
  7175.         }
  7176.         /* ============================================
  7177.            スマホ用 お見積りの詳細 ボトムシート
  7178.         ============================================ */
  7179.         .sp-detail-sheet { display: none; }
  7180.         .sp-detail-sheet.is-open {
  7181.             display: block;
  7182.             position: fixed;
  7183.             top: 0; left: 0; right: 0; bottom: 0;
  7184.             z-index: 2000;
  7185.         }
  7186.         .sp-detail-sheet__overlay {
  7187.             position: absolute;
  7188.             top: 0; left: 0; right: 0; bottom: 0;
  7189.             background: rgba(0,0,0,0.45);
  7190.         }
  7191.         .sp-detail-sheet__panel {
  7192.             position: absolute;
  7193.             left: 0; right: 0; bottom: 0;
  7194.             background: #fff;
  7195.             border-radius: 14px 14px 0 0;
  7196.             max-height: 82vh;
  7197.             display: flex;
  7198.             flex-direction: column;
  7199.             box-shadow: 0 -4px 20px rgba(0,0,0,0.25);
  7200.             padding-bottom: env(safe-area-inset-bottom);
  7201.             animation: spSheetUp 0.22s ease-out;
  7202.         }
  7203.         @keyframes spSheetUp {
  7204.             from { transform: translateY(100%); }
  7205.             to   { transform: translateY(0); }
  7206.         }
  7207.         .sp-detail-sheet__header {
  7208.             display: flex;
  7209.             align-items: center;
  7210.             justify-content: space-between;
  7211.             padding: 14px 16px;
  7212.             border-bottom: 1px solid #eee;
  7213.             flex: 0 0 auto;
  7214.         }
  7215.         .sp-detail-sheet__title { font-size: 16px; font-weight: bold; color: #333; }
  7216.         .sp-detail-sheet__close {
  7217.             background: none;
  7218.             border: none;
  7219.             font-size: 26px;
  7220.             line-height: 1;
  7221.             color: #888;
  7222.             cursor: pointer;
  7223.             padding: 0 4px;
  7224.         }
  7225.         .sp-detail-sheet__body {
  7226.             overflow-y: auto;
  7227.             -webkit-overflow-scrolling: touch;
  7228.             padding: 4px 0;
  7229.             flex: 1 1 auto;
  7230.         }
  7231.         .sp-detail-sheet__body ul { list-style: none; margin: 0; padding: 0; }
  7232.         .sp-detail-sheet__body li { border-bottom: 1px solid #f2f2f2; }
  7233.         .sp-detail-sheet__body .nav-link {
  7234.             display: flex;
  7235.             align-items: center;
  7236.             justify-content: space-between;
  7237.             padding: 12px 16px;
  7238.             color: #333;
  7239.             font-size: 14px;
  7240.         }
  7241.         .sp-detail-sheet__body .nav-link .float-right {
  7242.             float: none !important;
  7243.             font-weight: bold;
  7244.             white-space: nowrap;
  7245.             margin-left: auto;
  7246.         }
  7247.         .sp-detail-sheet__footer {
  7248.             display: flex;
  7249.             gap: 8px;
  7250.             padding: 12px 16px 16px;
  7251.             border-top: 1px solid #eee;
  7252.             flex: 0 0 auto;
  7253.         }
  7254.         .sp-detail-sheet__footer button {
  7255.             flex: 1 1 auto;
  7256.             padding: 12px;
  7257.             border-radius: 8px;
  7258.             font-size: 14px;
  7259.             font-weight: bold;
  7260.             cursor: pointer;
  7261.         }
  7262.         .sp-detail-sheet__invoice {
  7263.             background: #fff;
  7264.             border: 1px solid #17a2b8;
  7265.             color: #17a2b8;
  7266.         }
  7267.         .sp-detail-sheet__cart {
  7268.             background: #c00;
  7269.             border: 1px solid #c00;
  7270.             color: #fff;
  7271.         }
  7272.         /* ============================================
  7273.            商品タイプ選択 共通スタイル
  7274.         ============================================ */
  7275.         /* セクションラベル */
  7276.         .rp-section-label {
  7277.             font-size: 14px;
  7278.             font-weight: bold;
  7279.             color: #333;
  7280.             margin-bottom: 10px;
  7281.         }
  7282.         .rp-section-label span {
  7283.             font-weight: normal;
  7284.             color: #c00;
  7285.         }
  7286.         /* ---- 1. 画像付きカード ---- */
  7287.         .rp-card-group {
  7288.             display: flex;
  7289.             flex-wrap: wrap;
  7290.             gap: 8px;
  7291.             margin-bottom: 4px;
  7292.         }
  7293.         .rp-card {
  7294.             position: relative;
  7295.             cursor: pointer;
  7296.             touch-action: manipulation; /* drop iOS 300ms tap delay (#15) */
  7297.             -webkit-tap-highlight-color: rgba(0,0,0,0);
  7298.             /* iOS Safari: prevent the first tap from being consumed as a text
  7299.                selection (\"字だけ青くなる\" = selection highlight) which forced a
  7300.                2nd tap to actually switch the option (#15). */
  7301.             -webkit-user-select: none; -moz-user-select: none; user-select: none;
  7302.             -webkit-touch-callout: none;
  7303.             width: 110px;
  7304.             border: 2px solid #ddd;
  7305.             border-radius: 10px;
  7306.             overflow: hidden;
  7307.             transition: border-color 0.2s, box-shadow 0.2s;
  7308.             background: #fff;
  7309.             text-decoration: none;
  7310.             color: #333;
  7311.             display: block;
  7312.         }
  7313.         /* Gate :hover behind real hover-capable pointers. On iOS Safari a
  7314.            :hover rule that changes appearance makes the first tap apply the
  7315.            hover state and suppresses the click, so the option chip needed a
  7316.            second tap to fire its onclick (is-selected + price update). */
  7317.         @media (hover: hover) and (pointer: fine) {
  7318.             .rp-card:hover {
  7319.                 border-color: #999;
  7320.                 box-shadow: 0 2px 8px rgba(0,0,0,0.1);
  7321.             }
  7322.         }
  7323.         .rp-card.is-selected {
  7324.             border-color: #1a6fcf;
  7325.             box-shadow: 0 2px 10px rgba(26,111,207,0.25);
  7326.         }
  7327.         /* visually-hidden instead of display:none. A label wrapping a
  7328.            display:none radio fires its tap unreliably on iOS Safari (first tap
  7329.            often ignored -> \"2回タッチ\"). Keeping the input in the layout but
  7330.            invisible makes the first tap register. */
  7331.         .rp-card input[type=\"radio\"] {
  7332.             position: absolute; opacity: 0; width: 1px; height: 1px;
  7333.             margin: 0; pointer-events: none;
  7334.         }
  7335.         .rp-card__image {
  7336.             width: 100%;
  7337.             aspect-ratio: 1 / 1;
  7338.             object-fit: cover;
  7339.             display: block;
  7340.             background: #f5f5f5;
  7341.         }
  7342.         .rp-card__placeholder {
  7343.             width: 100%;
  7344.             aspect-ratio: 1 / 1;
  7345.             background: #f0f0f0;
  7346.             display: flex;
  7347.             align-items: center;
  7348.             justify-content: center;
  7349.             color: #bbb;
  7350.             font-size: 24px;
  7351.         }
  7352.         .rp-card__name {
  7353.             display: block;
  7354.             padding: 5px 5px;
  7355.             font-size: 11px;
  7356.             color: #333;
  7357.             text-align: center;
  7358.             line-height: 1.4;
  7359.             word-break: break-all;
  7360.         }
  7361.         .rp-card.is-selected .rp-card__name { color: #1a6fcf; font-weight: bold; }
  7362.         .rp-card.is-selected::after {
  7363.             content: \"✓\";
  7364.             position: absolute;
  7365.             top: 3px; right: 6px;
  7366.             color: #1a6fcf;
  7367.             font-size: 13px;
  7368.             font-weight: bold;
  7369.         }
  7370.         /* ---- 2. ボタン式ラジオ(画像なし・8個以内)---- */
  7371.         .rp-btn-group {
  7372.             display: flex;
  7373.             flex-wrap: wrap;
  7374.             gap: 8px;
  7375.             margin-bottom: 4px;
  7376.             max-width: 100%;
  7377.             min-width: 0;
  7378.         }
  7379.         .rp-btn {
  7380.             cursor: pointer;
  7381.             touch-action: manipulation; /* drop iOS 300ms tap delay (#15) */
  7382.             -webkit-tap-highlight-color: rgba(0,0,0,0);
  7383.             /* iOS Safari: block first-tap text selection so 1 tap switches (#15) */
  7384.             -webkit-user-select: none; -moz-user-select: none; user-select: none;
  7385.             -webkit-touch-callout: none;
  7386.             padding: 8px 14px;
  7387.             border: 2px solid #ddd;
  7388.             border-radius: 10px;
  7389.             font-size: 13px;
  7390.             color: #333;
  7391.             background: #fff;
  7392.             transition: border-color 0.2s, background 0.2s;
  7393.             white-space: normal;
  7394.             max-width: 100%;
  7395.             overflow-wrap: anywhere;
  7396.             text-decoration: none;
  7397.         }
  7398.         @media (hover: hover) and (pointer: fine) {
  7399.             .rp-btn:hover { border-color: #999; }
  7400.         }
  7401.         .rp-btn.is-selected {
  7402.             border-color: #1a6fcf;
  7403.             color: #1a6fcf;
  7404.             font-weight: bold;
  7405.             background: #f0f6ff;
  7406.         }
  7407.         .rp-btn input[type=\"radio\"] {
  7408.             position: absolute; opacity: 0; width: 1px; height: 1px;
  7409.             margin: 0; pointer-events: none;
  7410.         }
  7411.         /* iOS Safari \"2回タッチ\" fix for the type-selection link chips.
  7412.            The global theme stylesheet ships an ungated `a:hover{color:#296292}`
  7413.            (paired with `a{color:#337ab7;text-decoration:underline}`). Because
  7414.            .rp-btn / .rp-card are real <a> links, iOS Safari applies that hover
  7415.            colour on the FIRST tap — the chip text turns blue (#296292, the
  7416.            reported \"字だけ青くなる\") — and treats the tap as a hover, swallowing
  7417.            the navigation so a 2nd tap was needed. The local .rp-*:hover rules
  7418.            are already gated behind (hover:hover), but this inherited global
  7419.            rule was not. Pin the hover/active colour to the base/selected colour
  7420.            so tapping produces no visual change and the first tap navigates
  7421.            immediately. Higher specificity (0,2,0 / 0,3,0) overrides a:hover. */
  7422.         .rp-btn:hover,
  7423.         .rp-btn:active { color: #333; text-decoration: none; }
  7424.         .rp-btn.is-selected:hover,
  7425.         .rp-btn.is-selected:active { color: #1a6fcf; text-decoration: none; }
  7426.         .rp-card:hover,
  7427.         .rp-card:active { color: #333; text-decoration: none; }
  7428.         .rp-card:hover .rp-card__name,
  7429.         .rp-card:active .rp-card__name { color: #333; }
  7430.         .rp-card.is-selected:hover .rp-card__name,
  7431.         .rp-card.is-selected:active .rp-card__name { color: #1a6fcf; }
  7432.         /* ---- 選択肢が多い場合: 縦3段に収めて横スクロール(顧客要望「3列くらいで横スクロール」)---- */
  7433.         /* grid-auto-flow:column + 3行固定 → 選択肢が縦に最大3段、超過分は右へ伸び横スクロールで閲覧 */
  7434.         .rp-btn-group.is-scroll,
  7435.         .opt-btn-group.is-scroll {
  7436.             display: grid;
  7437.             grid-auto-flow: column;
  7438.             grid-template-rows: repeat(3, auto);
  7439.             grid-auto-columns: max-content;
  7440.             justify-content: start;
  7441.             align-items: start;
  7442.             gap: 8px;
  7443.             overflow-x: auto;
  7444.             overflow-y: hidden;
  7445.             -webkit-overflow-scrolling: touch;
  7446.             scrollbar-width: thin;
  7447.             /* 上下に余白を確保して、行の枠線が overflow クリップ/スクロールバーに
  7448.                切り取られないようにする(「文字列が長いと下枠が消える」対策)。 */
  7449.             padding: 2px 0 12px;
  7450.         }
  7451.         /* is-scroll(横スクロール)内では選択肢を折り返さず単一行に固定する。
  7452.            折り返すと行高が不揃いになり overflow-y:hidden で下枠が切れるため、
  7453.            長い選択肢は折り返さず横スクロールで見せる(本来の設計意図)。 */
  7454.         .rp-btn-group.is-scroll .rp-btn,
  7455.         .rp-btn-group.is-scroll .opt-btn,
  7456.         .opt-btn-group.is-scroll .rp-btn,
  7457.         .opt-btn-group.is-scroll .opt-btn {
  7458.             white-space: nowrap;
  7459.             word-break: normal;
  7460.             overflow-wrap: normal;
  7461.         }
  7462.         .rp-btn-group.is-scroll::-webkit-scrollbar,
  7463.         .opt-btn-group.is-scroll::-webkit-scrollbar {
  7464.             height: 6px;
  7465.         }
  7466.         .rp-btn-group.is-scroll::-webkit-scrollbar-thumb,
  7467.         .opt-btn-group.is-scroll::-webkit-scrollbar-thumb {
  7468.             background: #c0c0c0;
  7469.             border-radius: 3px;
  7470.         }
  7471.         /* ---- 3. プルダウン(画像なし・9個以上)---- */
  7472.         .rp-select-wrap {
  7473.             margin-bottom: 4px;
  7474.         }
  7475.         .rp-select {
  7476.             width: 100%;
  7477.             max-width: 420px;
  7478.             padding: 8px 12px;
  7479.             border: 2px solid #ddd;
  7480.             border-radius: 10px;
  7481.             font-size: 13px;
  7482.             color: #333;
  7483.             background: #fff;
  7484.             appearance: none;
  7485.             background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%23666' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E\");
  7486.             background-repeat: no-repeat;
  7487.             background-position: right 12px center;
  7488.             cursor: pointer;
  7489.         }
  7490.         .rp-select:focus {
  7491.             outline: none;
  7492.             border-color: #1a6fcf;
  7493.         }
  7494.         /* ---- オプション選択ボタン(枠線ラジオ)---- */
  7495.         .opt-btn-group {
  7496.             display: flex;
  7497.             flex-wrap: wrap;
  7498.             gap: 8px;
  7499.             padding: 6px 0;
  7500.             max-width: 100%;
  7501.             min-width: 0;
  7502.         }
  7503.         .opt-btn {
  7504.             cursor: pointer;
  7505.             touch-action: manipulation; /* drop iOS 300ms tap delay (#15) */
  7506.             -webkit-tap-highlight-color: rgba(0,0,0,0);
  7507.             /* iOS Safari: block first-tap text selection so 1 tap switches (#15) */
  7508.             -webkit-user-select: none; -moz-user-select: none; user-select: none;
  7509.             -webkit-touch-callout: none;
  7510.             padding: 7px 14px;
  7511.             border: 2px solid #ddd;
  7512.             border-radius: 10px;
  7513.             font-size: 13px;
  7514.             color: #333;
  7515.             background: #fff;
  7516.             transition: border-color 0.2s, background 0.2s;
  7517.             white-space: normal;
  7518.             max-width: 100%;
  7519.             overflow-wrap: anywhere;
  7520.             text-decoration: none;
  7521.         }
  7522.         @media (hover: hover) and (pointer: fine) {
  7523.             .opt-btn:hover { border-color: #999; }
  7524.         }
  7525.         .opt-btn.is-selected {
  7526.             border-color: #1a6fcf;
  7527.             color: #1a6fcf;
  7528.             font-weight: bold;
  7529.             background: #f0f6ff;
  7530.         }
  7531.         .opt-btn input[type=\"radio\"] {
  7532.             position: absolute; opacity: 0; width: 1px; height: 1px;
  7533.             margin: 0; pointer-events: none;
  7534.         }
  7535.         /* opt-btn with color swatch image. The label still works as a
  7536.            radio target — clicking the image checks the input. The text
  7537.            label stays under the image so users can still read the name. */
  7538.         .opt-btn--with-image {
  7539.             padding: 4px 6px 6px;
  7540.             white-space: normal;
  7541.             text-align: center;
  7542.             display: inline-flex;
  7543.             flex-direction: column;
  7544.             align-items: center;
  7545.             min-width: 96px;
  7546.             max-width: 140px;
  7547.         }
  7548.         .opt-btn--with-image .opt-btn__img {
  7549.             display: block;
  7550.             width: 88px;
  7551.             height: 66px;
  7552.             object-fit: cover;
  7553.             border-radius: 6px;
  7554.             margin-bottom: 4px;
  7555.             background: #f5f5f5;
  7556.         }
  7557.         .opt-btn--with-image .opt-btn__name {
  7558.             display: block;
  7559.             font-size: 11px;
  7560.             line-height: 1.3;
  7561.             color: inherit;
  7562.         }
  7563.         .opt-btn--with-image.is-selected .opt-btn__img {
  7564.             outline: 2px solid #1a6fcf;
  7565.             outline-offset: 1px;
  7566.         }
  7567.         /* sale_type=2 (内窓) 補助金対象ガラスの強調表示.
  7568.            補助金が出る性能区分 (真空断熱 / Low-E複層 等) のガラス選択肢に
  7569.            緑枠 + 「補助金対象」バッジを付け、選択前から判別できるようにする。 */
  7570.         .opt-btn--subsidy {
  7571.             border-color: #2e7d32;
  7572.         }
  7573.         .opt-btn--subsidy.is-selected {
  7574.             border-color: #1a6fcf;
  7575.         }
  7576.         .opt-btn__subsidy-badge {
  7577.             display: inline-block;
  7578.             margin-left: 6px;
  7579.             padding: 1px 6px;
  7580.             border-radius: 6px;
  7581.             background: #2e7d32;
  7582.             color: #fff;
  7583.             font-size: 11px;
  7584.             font-weight: bold;
  7585.             white-space: nowrap;
  7586.         }
  7587.         /* ============================================
  7588.            施工エリア案内
  7589.         ============================================ */
  7590.         .ec-areaNotice {
  7591.             margin: 16px 0;
  7592.             padding: 16px 20px;
  7593.             background: #f8f9fa;
  7594.             border-left: 4px solid #1a6fcf;
  7595.             border-radius: 0 8px 8px 0;
  7596.         }
  7597.         .ec-areaNotice__inner {
  7598.             display: flex;
  7599.             align-items: flex-start;
  7600.             gap: 12px;
  7601.         }
  7602.         .ec-areaNotice__icon {
  7603.             font-size: 22px;
  7604.             line-height: 1;
  7605.             flex-shrink: 0;
  7606.             margin-top: 2px;
  7607.         }
  7608.         .ec-areaNotice__body {
  7609.             flex: 1;
  7610.         }
  7611.         .ec-areaNotice__title {
  7612.             font-size: 13px;
  7613.             font-weight: bold;
  7614.             color: #1a6fcf;
  7615.             margin: 0 0 6px;
  7616.         }
  7617.         .ec-areaNotice__text {
  7618.             font-size: 13px;
  7619.             color: #444;
  7620.             line-height: 1.7;
  7621.             margin: 0;
  7622.         }
  7623.         .ec-areaNotice__text strong {
  7624.             color: #222;
  7625.         }
  7626.         .ec-areaNotice__link {
  7627.             display: inline-block;
  7628.             margin-top: 8px;
  7629.             font-size: 12px;
  7630.             color: #1a6fcf;
  7631.             text-decoration: underline;
  7632.         }
  7633.         .ec-areaNotice__link:hover {
  7634.             color: #0d4fa0;
  7635.         }
  7636.         /* ============================================
  7637.            SNSシェア + ブランド名 タイトル行
  7638.         ============================================ */
  7639.         .ec-productRole__titleRow {
  7640.             display: flex;
  7641.             align-items: center;
  7642.             justify-content: space-between;
  7643.             gap: 8px;
  7644.             margin-bottom: 4px;
  7645.         }
  7646.         .ec-productRole__titleRow .ec-headingTitle {
  7647.             margin: 0;
  7648.             flex: 1;
  7649.             font-size: 18px;
  7650.         }
  7651.         .ec-share-inline {
  7652.             display: flex;
  7653.             align-items: center;
  7654.             gap: 8px;
  7655.             flex-shrink: 0;
  7656.         }
  7657.         @media (max-width: 767px) {
  7658.             /* maker_area の float を解除して独立表示 */
  7659.             #maker_area {
  7660.                 float: none !important;
  7661.                 width: auto !important;
  7662.                 height: auto !important;
  7663.                 display: block;
  7664.                 margin-bottom: 4px;
  7665.             }
  7666.             /* タイトル行: 商品名が全幅を占有しSNSは右寄せ下段 */
  7667.             .ec-productRole__titleRow {
  7668.                 flex-wrap: wrap;
  7669.                 clear: both;
  7670.             }
  7671.             .ec-productRole__titleRow .ec-headingTitle {
  7672.                 flex: 1 1 100%;
  7673.                 font-size: 16px;
  7674.             }
  7675.             .ec-share-inline {
  7676.                 flex: 0 0 auto;
  7677.                 margin-left: auto;
  7678.             }
  7679.         }
  7680.         .ec-share-inline a {
  7681.             display: flex;
  7682.             align-items: center;
  7683.             justify-content: center;
  7684.             width: 32px;
  7685.             height: 32px;
  7686.             border-radius: 50%;
  7687.             font-size: 15px;
  7688.             color: #fff;
  7689.             text-decoration: none;
  7690.             transition: opacity 0.2s;
  7691.         }
  7692.         .ec-share-inline a:hover { opacity: 0.8; }
  7693.         .ec-share-inline .share-twitter  { background: #000; }
  7694.         .ec-share-inline .share-facebook { background: linear-gradient(45deg, #f09433, #e6683c, #dc2743, #cc2366, #bc1888); }
  7695.         .ec-share-inline .share-line     { background: #06c755; }
  7696.         /* description_detail下のシェアブロックはPC/スマホ共通で非表示(タイトル行に移動) */
  7697.         .ec-productRole__share { display: none; }
  7698.         /* ============================================
  7699.            PC用: 現在のお見積り額カード強調
  7700.         ============================================ */
  7701.         @media (min-width: 768px) {
  7702.             .mitsumori-card-pc {
  7703.                 border: 2px solid #1a6fcf !important;
  7704.                 border-radius: 10px !important;
  7705.                 box-shadow: 0 4px 16px rgba(26,111,207,0.18) !important;
  7706.                 margin-top: 20px;
  7707.                 overflow: hidden;
  7708.                 background: linear-gradient(135deg, #1a6fcf, #0d4fa0) !important;
  7709.             }
  7710.             .mitsumori-card-pc .card-header {
  7711.                 background: linear-gradient(135deg, #1a6fcf, #0d4fa0) !important;
  7712.                 color: #fff !important;
  7713.                 padding: 14px 16px !important;
  7714.                 border-bottom: none !important;
  7715.             }
  7716.             .mitsumori-card-pc .card-title {
  7717.                 color: #fff !important;
  7718.                 font-size: 15px !important;
  7719.                 font-weight: bold !important;
  7720.                 margin: 0 !important;
  7721.             }
  7722.             .mitsumori-card-pc #mitsumori_message {
  7723.                 font-size: 22px !important;
  7724.                 font-weight: bold !important;
  7725.                 color: #fff !important;
  7726.             }
  7727.             .mitsumori-card-pc .btn-tool {
  7728.                 color: #fff !important;
  7729.             }
  7730.             /* 合計行を大きく強調 */
  7731.             .mitsumori-card-pc .nav-item:first-child .nav-link {
  7732.                 font-size: 16px !important;
  7733.                 font-weight: bold !important;
  7734.                 color: #c00 !important;
  7735.                 background: #fff8f8 !important;
  7736.                 padding: 12px 16px !important;
  7737.             }
  7738.             .mitsumori-card-pc .nav-item:first-child #mitsumori_goukei {
  7739.                 font-size: 20px !important;
  7740.                 font-weight: bold !important;
  7741.                 color: #c00 !important;
  7742.             }
  7743.             /* card-body(明細リスト)を白背景に */
  7744.             .mitsumori-card-pc .card-body {
  7745.                 background: #fff !important;
  7746.             }
  7747.             .mitsumori-card-pc .card-footer {
  7748.                 background: #f8faff !important;
  7749.                 border-top: 1px solid #dce8fb !important;
  7750.                 padding: 12px 16px !important;
  7751.             }
  7752.         }
  7753.         @media (max-width: 767px) {
  7754.             /* スマホでは現在のお見積り額カードの強調スタイルをすべてリセット */
  7755.             .mitsumori-card-pc {
  7756.                 border: none !important;
  7757.                 border-radius: 0 !important;
  7758.                 box-shadow: none !important;
  7759.                 margin-top: 0 !important;
  7760.                 overflow: visible !important;
  7761.                 background: none !important;
  7762.                 /* sticky-top(position:sticky / z-index:1020) を解除。
  7763.                    そのままだと最下部で #sp-mitsumori-bar(z-index:1000) の上に
  7764.                    重なり、合計バーと文字が被るため通常フローへ戻す。 */
  7765.                 position: static !important;
  7766.                 z-index: auto !important;
  7767.             }
  7768.             .mitsumori-card-pc .card-header {
  7769.                 background: none !important;
  7770.                 color: inherit !important;
  7771.                 padding: inherit !important;
  7772.                 border-bottom: inherit !important;
  7773.             }
  7774.             .mitsumori-card-pc .card-title { color: inherit !important; }
  7775.             .mitsumori-card-pc #mitsumori_message { font-size: inherit !important; color: inherit !important; }
  7776.             .mitsumori-card-pc .btn-tool { color: inherit !important; }
  7777.             /* 折りたたみトグルボタン */
  7778.             .btn-mitsumori-toggle {
  7779.                 background: none !important;
  7780.                 border: 1px solid #aaa !important;
  7781.                 border-radius: 4px !important;
  7782.                 padding: 2px 8px !important;
  7783.                 font-size: 12px !important;
  7784.                 color: #333 !important;
  7785.                 line-height: 1.4 !important;
  7786.             }
  7787.             .btn-mitsumori-toggle .toggle-icon {
  7788.                 display: inline-block;
  7789.                 transition: transform 0.2s;
  7790.             }
  7791.             /* 展開状態: ▼→▲ */
  7792.             .card:not(.collapsed-card) .btn-mitsumori-toggle .toggle-icon::before {
  7793.                 content: \"▲ 閉じる\";
  7794.             }
  7795.             .card:not(.collapsed-card) .btn-mitsumori-toggle .toggle-icon {
  7796.                 display: none;
  7797.             }
  7798.             .card:not(.collapsed-card) .btn-mitsumori-toggle::after {
  7799.                 content: \"▲ 閉じる\";
  7800.                 font-size: 12px;
  7801.             }
  7802.             .mitsumori-card-pc .nav-item:first-child .nav-link {
  7803.                 font-size: inherit !important;
  7804.                 color: inherit !important;
  7805.                 background: none !important;
  7806.                 padding: inherit !important;
  7807.             }
  7808.             .mitsumori-card-pc .nav-item:first-child #mitsumori_goukei {
  7809.                 font-size: inherit !important;
  7810.                 color: inherit !important;
  7811.             }
  7812.             .mitsumori-card-pc .card-footer {
  7813.                 background: none !important;
  7814.                 border-top: inherit !important;
  7815.                 padding: inherit !important;
  7816.             }
  7817.             /* 横スクロール禁止 */
  7818.             body, html {
  7819.                 overflow-x: hidden;
  7820.                 max-width: 100vw;
  7821.             }
  7822.             /* ボタンの折り返しを許可(nowrapが原因で横スクロール発生するため) */
  7823.             .opt-btn,
  7824.             .rp-btn {
  7825.                 white-space: normal;
  7826.                 word-break: break-all;
  7827.             }
  7828.             /* エリア案内: スマホでコンパクト */
  7829.             .ec-areaNotice {
  7830.                 margin: 8px 0;
  7831.                 padding: 8px 10px;
  7832.                 border-left-width: 3px;
  7833.                 cursor: pointer;
  7834.             }
  7835.             .ec-areaNotice__inner {
  7836.                 flex-direction: row;
  7837.                 gap: 8px;
  7838.                 align-items: flex-start;
  7839.             }
  7840.             .ec-areaNotice__icon { font-size: 15px; }
  7841.             /* タイトル行: 展開トグル */
  7842.             .ec-areaNotice__title {
  7843.                 font-size: 11px;
  7844.                 margin-bottom: 3px;
  7845.                 display: flex;
  7846.                 justify-content: space-between;
  7847.                 align-items: center;
  7848.             }
  7849.             .ec-areaNotice__title::after {
  7850.                 content: \"▼\";
  7851.                 font-size: 9px;
  7852.                 color: #888;
  7853.                 margin-left: 6px;
  7854.                 transition: transform 0.2s;
  7855.             }
  7856.             .ec-areaNotice.is-open .ec-areaNotice__title::after {
  7857.                 transform: rotate(180deg);
  7858.             }
  7859.             /* 折りたたみ対象: 閉じた状態では非表示 */
  7860.             .ec-areaNotice__detail {
  7861.                 display: none;
  7862.             }
  7863.             .ec-areaNotice.is-open .ec-areaNotice__detail {
  7864.                 display: block;
  7865.             }
  7866.             .ec-areaNotice__text { font-size: 11px; line-height: 1.5; }
  7867.             .ec-areaNotice__text br { display: none; }
  7868.             .ec-areaNotice__link { font-size: 11px; margin-top: 3px; }
  7869.             .rp-card { width: calc(33.333% - 6px); min-width: 80px; }
  7870.             
  7871.             #sp-mitsumori-bar {
  7872.                 display: flex;
  7873.                 position: fixed;
  7874.                 bottom: 0;
  7875.                 left: 0;
  7876.                 right: 0;
  7877.                 z-index: 1000;
  7878.                 background: #fff;
  7879.                 border-top: 2px solid #e0e0e0;
  7880.                 box-shadow: 0 -2px 8px rgba(0,0,0,0.12);
  7881.                 align-items: center;
  7882.                 padding: 8px 10px calc(8px + env(safe-area-inset-bottom)) 10px;
  7883.                 gap: 8px;
  7884.             }
  7885.             #sp-mitsumori-bar .sp-bar__label {
  7886.                 font-size: 11px;
  7887.                 color: #666;
  7888.                 white-space: nowrap;
  7889.             }
  7890.             /* 価格ラッパ: 合計金額は最重要のため常に全桁表示する(縮小・省略しない)。
  7891.                幅が足りない場合は下のボタン側を縮める(flex 配分でボタンが先に縮む)。 */
  7892.             #sp-mitsumori-bar .sp-bar__pricewrap {
  7893.                 flex: 0 0 auto;
  7894.                 min-width: 0;
  7895.             }
  7896.             #sp-mitsumori-bar .sp-bar__price {
  7897.                 font-size: 18px;
  7898.                 font-weight: bold;
  7899.                 color: #c00;
  7900.                 white-space: nowrap;
  7901.             }
  7902.             #sp-mitsumori-bar .sp-bar__btn {
  7903.                 font-size: 12px;
  7904.                 padding: 8px 12px;
  7905.                 background: #333;
  7906.                 color: #fff;
  7907.                 border: none;
  7908.                 border-radius: 6px;
  7909.                 white-space: nowrap;
  7910.                 cursor: pointer;
  7911.                 position: relative;
  7912.                 display: inline-flex;
  7913.                 align-items: center;
  7914.                 gap: 6px;
  7915.                 flex: 1 1 auto;
  7916.                 min-width: 0;
  7917.                 justify-content: center;
  7918.             }
  7919.             #sp-mitsumori-bar .sp-bar__btn i {
  7920.                 font-size: 14px;
  7921.                 flex: 0 0 auto;
  7922.             }
  7923.             /* お見積りの詳細(内訳)を開くボタン。価格・カートボタンを圧迫しないよう
  7924.                最小幅のアイコン+短ラベルにし、幅不足時も縮まない固定幅で維持する。 */
  7925.             #sp-mitsumori-bar .sp-bar__detail-btn {
  7926.                 display: inline-flex;
  7927.                 flex-direction: column;
  7928.                 align-items: center;
  7929.                 justify-content: center;
  7930.                 gap: 2px;
  7931.                 flex: 0 0 auto;
  7932.                 padding: 4px 8px;
  7933.                 background: #fff;
  7934.                 color: #c00;
  7935.                 border: 1px solid #c00;
  7936.                 border-radius: 6px;
  7937.                 font-size: 10px;
  7938.                 font-weight: bold;
  7939.                 line-height: 1.1;
  7940.                 white-space: nowrap;
  7941.                 cursor: pointer;
  7942.             }
  7943.             #sp-mitsumori-bar .sp-bar__detail-btn i { font-size: 15px; }
  7944.             /* 幅が足りないときはボタンの文字を省略し、価格と数字を守る。 */
  7945.             #sp-mitsumori-bar .sp-bar__btn-label {
  7946.                 overflow: hidden;
  7947.                 text-overflow: ellipsis;
  7948.                 white-space: nowrap;
  7949.             }
  7950.             #sp-mitsumori-bar .sp-bar__cart-badge {
  7951.                 position: absolute;
  7952.                 top: -6px;
  7953.                 right: -6px;
  7954.                 background: #c00;
  7955.                 color: #fff;
  7956.                 border-radius: 50%;
  7957.                 min-width: 16px;
  7958.                 height: 16px;
  7959.                 font-size: 10px;
  7960.                 line-height: 16px;
  7961.                 padding: 0 4px;
  7962.                 font-weight: bold;
  7963.             }
  7964.             #sp-mitsumori-bar .sp-bar__home-btn {
  7965.                 display: inline-flex;
  7966.                 align-items: center;
  7967.                 justify-content: center;
  7968.                 width: 36px;
  7969.                 height: 36px;
  7970.                 flex: 0 0 auto;
  7971.                 border: 1px solid #ccc;
  7972.                 border-radius: 6px;
  7973.                 background: #fff;
  7974.                 color: #333;
  7975.                 text-decoration: none;
  7976.                 cursor: pointer;
  7977.             }
  7978.             #sp-mitsumori-bar .sp-bar__home-btn i {
  7979.                 font-size: 16px;
  7980.             }
  7981.             #sp-mitsumori-bar .sp-bar__home-btn:hover {
  7982.                 background: #f0f0f0;
  7983.             }
  7984.             /* 下部バーの高さ分ページ下部にpaddingを追加 (iOS safe-area 込み) */
  7985.             body {
  7986.                 padding-bottom: calc(80px + env(safe-area-inset-bottom));
  7987.             }
  7988.         }
  7989.         /* ============================================
  7990.            カート追加モーダル: 縦並び中央配置
  7991.         ============================================ */
  7992.         .add-cart-modal__wrap {
  7993.             text-align: center;
  7994.         }
  7995.         .add-cart-modal__header {
  7996.             font-size: 16px;
  7997.             margin: 20px 0 24px;
  7998.             text-align: center;
  7999.         }
  8000.         .add-cart-modal__actions {
  8001.             display: flex;
  8002.             flex-direction: column;
  8003.             align-items: center;
  8004.             gap: 16px;
  8005.             padding: 0 20px 20px;
  8006.         }
  8007.         .add-cart-modal__primary {
  8008.             display: inline-block;
  8009.             width: 80%;
  8010.             max-width: 320px;
  8011.             padding: 14px 20px;
  8012.             font-size: 15px;
  8013.             font-weight: bold;
  8014.             text-align: center;
  8015.             background: #d9534f;
  8016.             color: #fff !important;
  8017.             border-radius: 6px;
  8018.             text-decoration: none;
  8019.             cursor: pointer;
  8020.         }
  8021.         .add-cart-modal__primary:hover {
  8022.             background: #c9302c;
  8023.             color: #fff !important;
  8024.             text-decoration: none;
  8025.         }
  8026.         .add-cart-modal__secondary {
  8027.             display: inline-block;
  8028.             padding: 6px 14px;
  8029.             font-size: 12px;
  8030.             color: #666;
  8031.             border: 1px solid #ccc;
  8032.             border-radius: 4px;
  8033.             background: #fff;
  8034.             cursor: pointer;
  8035.         }
  8036.         .add-cart-modal__secondary:hover {
  8037.             background: #f0f0f0;
  8038.             color: #333;
  8039.         }
  8040.         @media (max-width: 767px) {
  8041.             .add-cart-modal__actions {
  8042.                 gap: 20px;
  8043.             }
  8044.         }
  8045.     </style>
  8046. {% endblock %}
  8047. {% block javascript %}
  8048.     <script>
  8049.         eccube.classCategories = {{ class_categories_as_json(Product)|raw }};
  8050.         // 規格2に選択肢を割り当てる。
  8051.         function fnSetClassCategories(form, classcat_id2_selected) {
  8052.             var \$form = \$(form);
  8053.             var product_id = \$form.find('input[name=product_id]').val();
  8054.             var \$sele1 = \$form.find('select[name=classcategory_id1]');
  8055.             var \$sele2 = \$form.find('select[name=classcategory_id2]');
  8056.             eccube.setClassCategories(\$form, product_id, \$sele1, \$sele2, classcat_id2_selected);
  8057.         }
  8058.         {% if form.classcategory_id2 is defined %}
  8059.         fnSetClassCategories(
  8060.             \$('#form1'), {{ form.classcategory_id2.vars.value|json_encode|raw }}
  8061.         );
  8062.         {% elseif form.classcategory_id1 is defined %}
  8063.         eccube.checkStock(\$('#form1'), {{ Product.id }}, {{ form.classcategory_id1.vars.value|json_encode|raw }}, null);
  8064.         {% endif %}
  8065.     </script>
  8066.     <script>
  8067.         \$(function() {
  8068.             // bfcache無効化
  8069.             \$(window).bind('pageshow', function(event) {
  8070.                 if (event.originalEvent.persisted) {
  8071.                     location.reload(true);
  8072.                 }
  8073.             });
  8074.             // Core Web Vital の Cumulative Layout Shift(CLS)対策のため
  8075.             // img タグに width, height が付与されている.
  8076.             // 630px 未満の画面サイズでは縦横比が壊れるための対策
  8077.             // see https://github.com/EC-CUBE/ec-cube/pull/5023
  8078.             \$('.ec-grid2__cell').hide();
  8079.             var removeSize = function () {
  8080.                 \$('.slide-item').height('');
  8081.                 \$('.slide-item img')
  8082.                     .removeAttr('width')
  8083.                     .removeAttr('height')
  8084.                     .removeAttr('style');
  8085.             };
  8086.             var slickInitial = function(slick) {
  8087.                 \$('.ec-grid2__cell').fadeIn(1500);
  8088.                 var baseHeight = \$(slick.target).height();
  8089.                 var baseWidth = \$(slick.target).width();
  8090.                 var rate = baseWidth / baseHeight;
  8091. \t\t\t\tif(baseHeight * rate < 400){
  8092. \t                \$('.slide-item').height(baseHeight * rate); // 余白を削除する
  8093. \t\t\t\t}else{
  8094. \t                \$('.slide-item').height(400); // 余白を削除する
  8095. \t\t\t\t}
  8096.                 // transform を使用することでCLSの影響を受けないようにする
  8097.                 \$('.slide-item img')
  8098.                     .css(
  8099.                         {
  8100.                             'transform-origin': 'top left',
  8101.                             'transform': 'scaleY(' + rate + ')',
  8102.                             'transition': 'transform .1s'
  8103.                         }
  8104.                     );
  8105.                 // 正しいサイズに近くなったら属性を解除する
  8106.                 setTimeout(removeSize, 500);
  8107.             };
  8108.             \$('.item_visual').on('init', slickInitial);
  8109.             // リサイズ時は CLS の影響を受けないため属性を解除する
  8110.             \$(window).resize(removeSize);
  8111.             \$('.item_visual').slick({
  8112.                 dots: false,
  8113.                 arrows: true,
  8114.                 responsive: [{
  8115.                     breakpoint: 768,
  8116.                     settings: {
  8117.                         dots: true,
  8118.                 \t\tarrows: false
  8119.                     }
  8120.                 }]
  8121.             });
  8122.             \$('.slideThumb').on('click', function() {
  8123.                 var index = \$(this).attr('data-index');
  8124.                 \$('.item_visual').slick('slickGoTo', index, false);
  8125.             })
  8126.         });
  8127.     </script>
  8128.     <script>
  8129.         \$(function() {
  8130.             \$('.add-cart').on('click', function(event) {
  8131.                 {% if form.classcategory_id1 is defined %}
  8132.                 // 規格1フォームの必須チェック
  8133.                 if (\$('#classcategory_id1').val() == '__unselected' || \$('#classcategory_id1').val() == '') {
  8134.                     \$('#classcategory_id1')[0].setCustomValidity('{{ '項目が選択されていません'|trans }}');
  8135.                     return true;
  8136.                 } else {
  8137.                     \$('#classcategory_id1')[0].setCustomValidity('');
  8138.                 }
  8139.                 {% endif %}
  8140.                 {% if form.classcategory_id2 is defined %}
  8141.                 // 規格2フォームの必須チェック
  8142.                 if (\$('#classcategory_id2').val() == '__unselected' || \$('#classcategory_id2').val() == '') {
  8143.                     \$('#classcategory_id2')[0].setCustomValidity('{{ '項目が選択されていません'|trans }}');
  8144.                     return true;
  8145.                 } else {
  8146.                     \$('#classcategory_id2')[0].setCustomValidity('');
  8147.                 }
  8148.                 {% endif %}
  8149.                 // タイプ2: カート送信直前に set_count を quantity に同期
  8150.                 if(\$('#set_count').length){
  8151.                     var _sc = parseInt(\$('#set_count').val()) || 1;
  8152.                     \$('#quantity').val(_sc);
  8153.                     \$('input[name=\"quantity\"]').val(_sc);
  8154.                 }
  8155.                 // 個数フォームのチェック
  8156.                 if (\$('#quantity').val() < 1) {
  8157.                     \$('#quantity')[0].setCustomValidity('{{ '1以上で入力してください。'|trans }}');
  8158.                     return true;
  8159.                 } else {
  8160.                     \$('#quantity')[0].setCustomValidity('');
  8161.                 }
  8162.                 event.preventDefault();
  8163.                 \$form = \$('#form1');
  8164.                 \$.ajax({
  8165.                     url: \$form.attr('action'),
  8166.                     type: \$form.attr('method'),
  8167.                     data: \$form.serialize(),
  8168.                     dataType: 'json',
  8169.                     beforeSend: function(xhr, settings) {
  8170.                         // Buttonを無効にする
  8171.                         \$('.add-cart').prop('disabled', true);
  8172.                     }
  8173.                 }).done(function(data) {
  8174.                     // レスポンス内のメッセージをalertで表示
  8175.                     \$.each(data.messages, function() {
  8176.                         \$('#ec-modal-header').text(this);
  8177.                     });
  8178.                     \$('.ec-modal').show()
  8179.                     // カートブロックを更新する
  8180.                     \$.ajax({
  8181.                         url: \"{{ url('block_cart') }}\",
  8182.                         type: 'GET',
  8183.                         dataType: 'html'
  8184.                     }).done(function(html) {
  8185.                         \$('.ec-headerRole__cart').html(html);
  8186.                     });
  8187.                 }).fail(function(data) {
  8188.                     alert('{{ 'カートへの追加に失敗しました。'|trans }}');
  8189.                 }).always(function(data) {
  8190.                     // Buttonを有効にする
  8191.                     \$('.add-cart').prop('disabled', false);
  8192.                 });
  8193.             });
  8194.         });
  8195.         \$('.ec-modal-wrap').on('click', function(e) {
  8196.             // モーダル内の処理は外側にバブリングさせない
  8197.             e.stopPropagation();
  8198.         });
  8199.         \$('.ec-modal-overlay, .ec-modal, .ec-modal-close, .ec-inlineBtn--cancel').on('click', function() {
  8200.             \$('.ec-modal').hide()
  8201.         });
  8202. \t\tvar pw = \"{% if mitsumori_json %}{{ mitsumori_json.pw }}{% endif %}\";
  8203. \t\tvar pd = \"{% if mitsumori_json %}{{ mitsumori_json.pd }}{% endif %}\";
  8204. \t\tvar ph = \"{% if mitsumori_json %}{{ mitsumori_json.ph }}{% endif %}\";
  8205. \t\tvar pm = \"{% if mitsumori_json %}{{ mitsumori_json.pm }}{% endif %}\";
  8206. \t\tvar pc = \"{% if mitsumori_json %}{{ mitsumori_json.pc }}{% endif %}\";
  8207. \t\t// option1 / option2: カテゴリ別 option 軸 (um: タイプ=subtype, fe: ct_up 等)
  8208. \t\tvar option1 = \"{% if mitsumori_json and mitsumori_json.option1 is defined %}{{ mitsumori_json.option1 }}{% endif %}\";
  8209. \t\tvar option2 = \"{% if mitsumori_json and mitsumori_json.option2 is defined %}{{ mitsumori_json.option2 }}{% endif %}\";
  8210. \t\tvar op0 = \"{% if mitsumori_json %}{{ mitsumori_json.op[0] }}{% endif %}\";
  8211. \t\tvar op1 = \"{% if mitsumori_json %}{{ mitsumori_json.op[1] }}{% endif %}\";
  8212. \t\tvar op2 = \"{% if mitsumori_json %}{{ mitsumori_json.op[2] }}{% endif %}\";
  8213. \t\tvar op3 = \"{% if mitsumori_json %}{{ mitsumori_json.op[3] }}{% endif %}\";
  8214. \t\tvar op4 = \"{% if mitsumori_json %}{{ mitsumori_json.op[4] }}{% endif %}\";
  8215. \t\tvar op5 = \"{% if mitsumori_json %}{{ mitsumori_json.op[5] }}{% endif %}\";
  8216. \t\tvar op6 = \"{% if mitsumori_json %}{{ mitsumori_json.op[6] }}{% endif %}\";
  8217. \t\tvar op7 = \"{% if mitsumori_json %}{{ mitsumori_json.op[7] }}{% endif %}\";
  8218. \t\tvar op8 = \"{% if mitsumori_json %}{{ mitsumori_json.op[8] }}{% endif %}\";
  8219. \t\tvar op9 = \"{% if mitsumori_json %}{{ mitsumori_json.op[9] }}{% endif %}\";
  8220. \t\tvar op10 = \"{% if mitsumori_json %}{{ mitsumori_json.op[10] }}{% endif %}\";
  8221. \t\tconst formatter = new Intl.NumberFormat('ja-JP');
  8222. \t\t// ============================================================
  8223. \t\t//  free_area 1 エントリのスキーマ(11 キー固定)
  8224. \t\t// ============================================================
  8225. \t\t//   w           : 幅 (string, 例 \"239.9cm\" / tf は \"1m\")
  8226. \t\t//   d           : 奥行
  8227. \t\t//   h           : 高さ (tf はロール長 \"10m\")
  8228. \t\t//   m           : 素材
  8229. \t\t//   c           : カラー
  8230. \t\t//   price       : 販売価格 (税抜、amount=1 ベース)
  8231. \t\t//   unit_price  : 商品 per-unit 増分 (税抜、AMOUNT_CATEGORIES のみ)
  8232. \t\t//   maker_price : メーカー価格 (税抜)
  8233. \t\t//   ct          : 基本工事費 (税抜、amount=1 ベース)
  8234. \t\t//   option1     : fe → ct_up / その他カテゴリ → category-specific
  8235. \t\t//   option2     : um → ct_up / その他カテゴリ → category-specific
  8236. \t\t//
  8237. \t\t//  ct4 (設置場所) / ct5 (撤去) / ct6 (残土) は option_area 側で扱う.
  8238. \t\t// ============================================================
  8239. \t\t// 施工オプション定義(option_area)— 各エントリ {name, comment, on, off, price}
  8240. \t\tvar op_data = {{ op_json|default('[]')|raw }};
  8241. \t\t// option_item_area:
  8242. \t\t//   tg 用 — block 別オプション差額表
  8243. \t\t//     { axis_labels: {F:'床材',front:'前面型',side1:'右側面型',side2:'左側面型'},
  8244. \t\t//       blocks: { 'W_label|D_label': { F:[{idx,label,diff},...], front:[...], side1:[...], side2:[...] }, ... } }
  8245. \t\t//   fe (sale_type=4) 用 — ブロックの種類×段数の差額表 (fe_block キー)
  8246. \t\t//     { fe_block: { depends_on_name: '...', depends_on_value: '...',
  8247. \t\t//                   title: '...', default_key: '...',
  8248. \t\t//                   choices: [{key,label,price}, ...] } }
  8249. \t\t// 該当しないカテゴリでは fe_block は null. axis_labels/blocks は空.
  8250. \t\tvar oi_data = {{ oi_json|default('{\"axis_labels\":{},\"blocks\":{},\"fe_block\":null}')|raw }};
  8251. \t\t// 選択中の tg オプション差額 (axis -> selected choice_idx). ラジオ click で更新される.
  8252. \t\tvar oi_selected = { F: 1, front: 1, side1: 1, side2: 1 };
  8253. \t\t// 選択中の fe ブロック種類×段数 (key 文字列). 既定は oi_data.fe_block.default_key.
  8254. \t\tvar fe_block_selected = (oi_data && oi_data.fe_block && oi_data.fe_block.default_key) || '';
  8255. \t\t// sale_type ID(mtb_sale_type の id。本サイトでの意味は次の通り):
  8256. \t\t//   1 通常 / 2 補助金窓 / 3 物置 / 4 フェンス / 5 デッキ / 6 芝生 / 9 商品のみ
  8257. \t\tvar SALE_TYPE_ID = {{ ProductClass.SaleType.id }};
  8258. \t\t{# option1 / option2 ラベルをカテゴリ別に決定 (sh=31, rd=43, mo=15) — 以降の UI / JS 両方で使用 #}
  8259. \t\t{% set option1_label = 'オプション1' %}
  8260. \t\t{% set option2_label = 'オプション2' %}
  8261. \t\t{% if Product.ProductCategories is not empty %}
  8262. \t\t\t{% for pcat in Product.ProductCategories %}
  8263. \t\t\t\t{% if pcat.category_id == 31 %}{% set option1_label = 'サイズプリセット' %}{% set option2_label = '駆動方式' %}{% endif %}
  8264. \t\t\t\t{% if pcat.category_id == 43 %}{% set option1_label = 'ランマ' %}{% set option2_label = 'タイプ' %}{% endif %}
  8265. \t\t\t\t{% if pcat.category_id == 15 %}{% set option1_label = '棚タイプ' %}{% endif %}
  8266. \t\t\t\t{% if pcat.category_id == 17 %}{% set option1_label = '窓タイプ' %}{% endif %}
  8267. \t\t\t{% endfor %}
  8268. \t\t{% endif %}
  8269. \t\t// 消費税率(pp.price/pp.ct/op_data.price は scraper が税抜で保存しているため、
  8270. \t\t// calcGoukei 出口で 1+TAX_RATE を掛けて税込 mitsumori_goukei にする)
  8271. \t\tvar TAX_RATE = 0.10;
  8272. \t\tfunction toIncTax(v) { return Math.round(v * (1 + TAX_RATE)); }
  8273. \t\t/**
  8274. \t\t * tg 用 block 別オプション差額の集計.
  8275. \t\t *   現選択 (W, D) から block key を作り、oi_data.blocks[blockKey] を取得.
  8276. \t\t *   各 axis (F/front/side1/side2) で oi_selected[axis] の choice の diff を合計.
  8277. \t\t * 戻り値: { total: 差額合計(税抜), items: [{name, label, diff}, ...] }
  8278. \t\t *   block が無い (tg 以外 / 該当 (W,D) が未取得) なら total=0.
  8279. \t\t */
  8280. \t\tfunction collectOptionItems(curW, curD) {
  8281. \t\t\tvar result = { total: 0, items: [] };
  8282. \t\t\tif (!oi_data || !oi_data.blocks) return result;
  8283. \t\t\tvar blockKey = (curW || '') + '|' + (curD || '');
  8284. \t\t\tvar block = oi_data.blocks[blockKey];
  8285. \t\t\tif (!block) return result;
  8286. \t\t\tvar axes = ['F', 'front', 'side1', 'side2'];
  8287. \t\t\tfor (var i = 0; i < axes.length; i++) {
  8288. \t\t\t\tvar axis = axes[i];
  8289. \t\t\t\tvar choices = block[axis];
  8290. \t\t\t\tif (!choices || !choices.length) continue;
  8291. \t\t\t\tvar idx = oi_selected[axis] || 1;
  8292. \t\t\t\tvar pick = null;
  8293. \t\t\t\tfor (var j = 0; j < choices.length; j++) {
  8294. \t\t\t\t\tif (parseInt(choices[j].idx) === parseInt(idx)) { pick = choices[j]; break; }
  8295. \t\t\t\t}
  8296. \t\t\t\tif (!pick) pick = choices[0];
  8297. \t\t\t\tvar diff = parseInt(pick.diff) || 0;
  8298. \t\t\t\tresult.total += diff;
  8299. \t\t\t\tresult.items.push({
  8300. \t\t\t\t\tname:  oi_data.axis_labels[axis] || axis,
  8301. \t\t\t\t\tlabel: pick.label,
  8302. \t\t\t\t\tdiff:  diff,
  8303. \t\t\t\t});
  8304. \t\t\t}
  8305. \t\t\treturn result;
  8306. \t\t}
  8307. \t\t/**
  8308. \t\t * tg ラジオ群を block 別に DOM へ描画する.
  8309. \t\t *   W/D が確定したら現 block の 4 軸 (F/front/side1/side2) ラジオを #tg-options 要素に出す.
  8310. \t\t *   block が空なら #tg-options を空にする.
  8311. \t\t */
  8312. \t\tfunction renderOptionItemRadios(curW, curD) {
  8313. \t\t\tvar \$box = \$('#tg-options');
  8314. \t\t\tif (!\$box.length) return;
  8315. \t\t\t\$box.empty();
  8316. \t\t\tif (!oi_data || !oi_data.blocks) return;
  8317. \t\t\tvar blockKey = (curW || '') + '|' + (curD || '');
  8318. \t\t\tvar block = oi_data.blocks[blockKey];
  8319. \t\t\tif (!block) return;
  8320. \t\t\tvar axes = ['F', 'front', 'side1', 'side2'];
  8321. \t\t\taxes.forEach(function(axis) {
  8322. \t\t\t\tvar choices = block[axis];
  8323. \t\t\t\tif (!choices || !choices.length) return;
  8324. \t\t\t\tvar axisLabel = (oi_data.axis_labels && oi_data.axis_labels[axis]) || axis;
  8325. \t\t\t\tvar \$section = \$('<div class=\"form-group tg-axis\"></div>');
  8326. \t\t\t\t\$section.append('<p class=\"rp-section-label\"><strong>' + axisLabel + '</strong>: <span class=\"tg-axis-selected\"></span></p>');
  8327. \t\t\t\tvar \$list = \$('<div class=\"tg-choice-list\"></div>');
  8328. \t\t\t\tchoices.forEach(function(ch, i) {
  8329. \t\t\t\t\tvar inputId = 'tg_' + axis + '_' + ch.idx;
  8330. \t\t\t\t\tvar name = 'tg_' + axis;
  8331. \t\t\t\t\tvar checked = (parseInt(ch.idx) === parseInt(oi_selected[axis] || 1)) ? ' checked' : '';
  8332. \t\t\t\t\tvar diffTxt = ch.diff > 0 ? '+' + formatter.format(ch.diff) + '円' : (ch.diff < 0 ? formatter.format(ch.diff) + '円' : '±0');
  8333. \t\t\t\t\t\$list.append(
  8334. \t\t\t\t\t\t'<label class=\"tg-choice\"><input type=\"radio\" name=\"' + name + '\" id=\"' + inputId + '\" value=\"' + ch.idx + '\" data-axis=\"' + axis + '\"' + checked + '> ' +
  8335. \t\t\t\t\t\tch.label + '<span class=\"tg-diff\">(' + diffTxt + ')</span></label>'
  8336. \t\t\t\t\t);
  8337. \t\t\t\t});
  8338. \t\t\t\t\$section.append(\$list);
  8339. \t\t\t\t\$box.append(\$section);
  8340. \t\t\t});
  8341. \t\t\t// ラジオ click で oi_selected を更新 → 再計算
  8342. \t\t\t\$box.off('change.tg').on('change.tg', 'input[type=\"radio\"][data-axis]', function() {
  8343. \t\t\t\tvar axis = \$(this).data('axis');
  8344. \t\t\t\toi_selected[axis] = parseInt(\$(this).val()) || 1;
  8345. \t\t\t\tmitsumori_simulation('refresh', '');
  8346. \t\t\t});
  8347. \t\t\tupdateOptionItemSelectedLabels();
  8348. \t\t}
  8349. \t\tfunction updateOptionItemSelectedLabels() {
  8350. \t\t\t\$('#tg-options .tg-axis').each(function() {
  8351. \t\t\t\tvar \$sel = \$(this).find('input[type=\"radio\"]:checked');
  8352. \t\t\t\tif (!\$sel.length) return;
  8353. \t\t\t\tvar label = \$sel.parent().contents().filter(function() { return this.nodeType === 3; }).text().trim();
  8354. \t\t\t\t\$(this).find('.tg-axis-selected').text(label);
  8355. \t\t\t});
  8356. \t\t}
  8357. \t\t// =========================================================
  8358. \t\t// fe (sale_type=4) ブロック種類×段数 サブ UI
  8359. \t\t// =========================================================
  8360. \t\t/**
  8361. \t\t * fe_block の親オプション (= op_data 内の「ご希望のフェンス設置方法」 entry)
  8362. \t\t * を name でルックアップし、その index を返す. 見つからなければ -1.
  8363. \t\t *   fe_block.depends_on_name が設定されていればそれで照合.
  8364. \t\t *   未設定なら 'ご希望のフェンス設置方法' を含む name にフォールバック.
  8365. \t\t */
  8366. \t\tfunction findFeBlockParentOpIndex() {
  8367. \t\t\tif (!oi_data || !oi_data.fe_block) return -1;
  8368. \t\t\tvar needle = oi_data.fe_block.depends_on_name || 'ご希望のフェンス設置方法';
  8369. \t\t\tfor (var i = 0; i < op_data.length; i++) {
  8370. \t\t\t\tif (!op_data[i] || !op_data[i].name) continue;
  8371. \t\t\t\tif (op_data[i].name.indexOf(needle) >= 0) return i;
  8372. \t\t\t}
  8373. \t\t\treturn -1;
  8374. \t\t}
  8375. \t\t/**
  8376. \t\t * fe_block の現在の選択値の price (税抜) と choice 内容を集計.
  8377. \t\t *   親オプション (= 'ご希望のフェンス設置方法') が depends_on_value を選んでいる
  8378. \t\t *   ときだけ加算する. それ以外 (既存ブロック側 / 親未選択) は price=0.
  8379. \t\t * 戻り値: { price: 0|N, choice: {key,label,price}|null, active: bool }
  8380. \t\t */
  8381. \t\tfunction collectFeBlock() {
  8382. \t\t\tvar result = { price: 0, choice: null, active: false };
  8383. \t\t\tif (SALE_TYPE_ID !== 4) return result;
  8384. \t\t\tif (!oi_data || !oi_data.fe_block) return result;
  8385. \t\t\tif (!oi_data.fe_block.choices || !oi_data.fe_block.choices.length) return result;
  8386. \t\t\tvar parentIdx = findFeBlockParentOpIndex();
  8387. \t\t\tif (parentIdx < 0) return result;
  8388. \t\t\tvar ops = [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10];
  8389. \t\t\tvar parentSel = ops[parentIdx];
  8390. \t\t\tvar triggerValue = oi_data.fe_block.depends_on_value || '新規にブロック積みを行う';
  8391. \t\t\tif (parentSel !== triggerValue) return result;  // 親が新規ブロック積み以外なら無加算
  8392. \t\t\tresult.active = true;
  8393. \t\t\tvar choices = oi_data.fe_block.choices;
  8394. \t\t\tvar pick = null;
  8395. \t\t\tfor (var j = 0; j < choices.length; j++) {
  8396. \t\t\t\tif (choices[j].key === fe_block_selected) { pick = choices[j]; break; }
  8397. \t\t\t}
  8398. \t\t\tif (!pick) pick = choices[0];
  8399. \t\t\tresult.choice = pick;
  8400. \t\t\tresult.price  = parseInt(pick.price) || 0;
  8401. \t\t\treturn result;
  8402. \t\t}
  8403. \t\t/**
  8404. \t\t * fe_block ラジオ群を #fe-block-options 要素に描画する.
  8405. \t\t *   active=false (親が「新規にブロック積み」以外) のときは非表示.
  8406. \t\t */
  8407. \t\tfunction renderFeBlockRadios() {
  8408. \t\t\tvar \$box = \$('#fe-block-options');
  8409. \t\t\tif (!\$box.length) return;
  8410. \t\t\tif (!oi_data || !oi_data.fe_block || !oi_data.fe_block.choices) {
  8411. \t\t\t\t\$box.empty().hide();
  8412. \t\t\t\treturn;
  8413. \t\t\t}
  8414. \t\t\tvar parentIdx = findFeBlockParentOpIndex();
  8415. \t\t\tif (parentIdx < 0) {
  8416. \t\t\t\t\$box.empty().hide();
  8417. \t\t\t\treturn;
  8418. \t\t\t}
  8419. \t\t\tvar ops = [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10];
  8420. \t\t\tvar triggerValue = oi_data.fe_block.depends_on_value || '新規にブロック積みを行う';
  8421. \t\t\tvar visible = (ops[parentIdx] === triggerValue);
  8422. \t\t\tif (!visible) {
  8423. \t\t\t\t\$box.hide();
  8424. \t\t\t\treturn;
  8425. \t\t\t}
  8426. \t\t\tvar fb = oi_data.fe_block;
  8427. \t\t\t\$box.empty();
  8428. \t\t\tvar \$title = \$('<p class=\"rp-section-label\"><strong>' + (fb.title || 'ブロックの種類と段数') + '</strong></p>');
  8429. \t\t\t\$box.append(\$title);
  8430. \t\t\t// 他オプション群と同じ .opt-btn-group / .opt-btn 形式で描画.
  8431. \t\t\t//   生の <label><input type=radio> ... 形式だと CSS 定義が無く
  8432. \t\t\t//   ラベル折り返し・縦ズレ・隣接 opt-btn との間隔不揃いが発生する.
  8433. \t\t\tvar \$list = \$('<div class=\"opt-btn-group\" style=\"flex-direction:column;align-items:stretch;\"></div>');
  8434. \t\t\tfb.choices.forEach(function(ch) {
  8435. \t\t\t\tvar inputId = 'fe_block_' + ch.key;
  8436. \t\t\t\tvar isSel   = (ch.key === fe_block_selected);
  8437. \t\t\t\tvar checked = isSel ? ' checked' : '';
  8438. \t\t\t\tvar selCls  = isSel ? ' is-selected' : '';
  8439. \t\t\t\tvar priceTxt = (parseInt(ch.price) || 0) > 0
  8440. \t\t\t\t\t? ' <span class=\"fe-block-price\" style=\"margin-left:6px;color:#666;font-size:12px;white-space:nowrap;\">(+' + formatter.format(toIncTax(parseInt(ch.price))) + '円 税込)</span>'
  8441. \t\t\t\t\t: '';
  8442. \t\t\t\t\$list.append(
  8443. \t\t\t\t\t'<label class=\"opt-btn' + selCls + '\" style=\"text-align:left;display:flex;align-items:center;flex-wrap:wrap;\">' +
  8444. \t\t\t\t\t'<input type=\"radio\" name=\"fe_block\" id=\"' + inputId + '\" value=\"' + ch.key + '\"' + checked + '>' +
  8445. \t\t\t\t\t'<span class=\"fe-block-label\">' + ch.label + '</span>' +
  8446. \t\t\t\t\tpriceTxt +
  8447. \t\t\t\t\t'</label>'
  8448. \t\t\t\t);
  8449. \t\t\t});
  8450. \t\t\t\$box.append(\$list);
  8451. \t\t\t\$box.show();
  8452. \t\t\t\$box.off('change.fe_block').on('change.fe_block', 'input[type=\"radio\"][name=\"fe_block\"]', function() {
  8453. \t\t\t\tfe_block_selected = \$(this).val();
  8454. \t\t\t\t// is-selected 切替 (opt-btn 形式共通)
  8455. \t\t\t\t\$box.find('label.opt-btn').removeClass('is-selected');
  8456. \t\t\t\t\$(this).closest('label.opt-btn').addClass('is-selected');
  8457. \t\t\t\tmitsumori_simulation('refresh', '');
  8458. \t\t\t});
  8459. \t\t}
  8460. \t\t/**
  8461. \t\t * fe (sale_type=4) で op_data エントリの連動表示制御.
  8462. \t\t *   親「ご希望のフェンス設置方法」の選択値に応じて、
  8463. \t\t *     - 「既存ブロックに穴空け工事が必要ですか?」 entry を表示/非表示
  8464. \t\t *   切替の trigger は親選択値の文字列で判定 (entry index にハードコードしない).
  8465. \t\t */
  8466. \t\tfunction updateFeOpConditionalVisibility() {
  8467. \t\t\tif (SALE_TYPE_ID !== 4) return;
  8468. \t\t\tvar parentIdx = findFeBlockParentOpIndex();
  8469. \t\t\tif (parentIdx < 0) return;
  8470. \t\t\tvar ops = [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10];
  8471. \t\t\tvar parentSel = ops[parentIdx];
  8472. \t\t\t// 親が「既存ブロックに設置する」 (= off 側) のとき穴空け entry を表示
  8473. \t\t\tvar triggerOffValue = (op_data[parentIdx] && op_data[parentIdx].off) || '既存ブロックに設置する';
  8474. \t\t\t\$('div[data-op-name]').each(function() {
  8475. \t\t\t\tvar n = \$(this).attr('data-op-name') || '';
  8476. \t\t\t\tif (n.indexOf('穴空け') >= 0) {
  8477. \t\t\t\t\tif (parentSel === triggerOffValue) {
  8478. \t\t\t\t\t\t\$(this).show();
  8479. \t\t\t\t\t} else {
  8480. \t\t\t\t\t\t\$(this).hide();
  8481. \t\t\t\t\t}
  8482. \t\t\t\t}
  8483. \t\t\t});
  8484. \t\t}
  8485. \t\t/**
  8486. \t\t * 選択中の施工オプションを集計し、ON選択分の price を合計する.
  8487. \t\t * 戻り値: { total: 合計金額, items: [{name, value, price}, ...] }
  8488. \t\t */
  8489. \t\tfunction collectOptions() {
  8490. \t\t\tvar ops = [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10];
  8491. \t\t\tvar total = 0;
  8492. \t\t\tvar items = [];
  8493. \t\t\tfor (var i = 0; i < ops.length; i++) {
  8494. \t\t\t\tif (!op_data[i] || !op_data[i].name) continue;
  8495. \t\t\t\tvar sel = ops[i];
  8496. \t\t\t\tif (!sel) continue;
  8497. \t\t\t\tvar price = parseInt(op_data[i].price) || 0;
  8498. \t\t\t\t// 「ON」選択時のみ加算(OFF や「不要」「商品購入のみ」は加算しない)
  8499. \t\t\t\tvar isOn = (sel === op_data[i].on);
  8500. \t\t\t\titems.push({
  8501. \t\t\t\t\tname:  op_data[i].name,
  8502. \t\t\t\t\tvalue: sel,
  8503. \t\t\t\t\tprice: isOn ? price : 0,
  8504. \t\t\t\t\ton:    op_data[i].on,
  8505. \t\t\t\t\toff:   op_data[i].off,
  8506. \t\t\t\t});
  8507. \t\t\t\tif (isOn) total += price;
  8508. \t\t\t}
  8509. \t\t\t// fe (sale_type=4) のブロック種類×段数 分を items / total に統合.
  8510. \t\t\t// 親オプション「ご希望のフェンス設置方法」 が 「新規にブロック積みを行う」 のとき
  8511. \t\t\t// だけ加算される (collectFeBlock 内で判定済み).
  8512. \t\t\tvar fb = collectFeBlock();
  8513. \t\t\tif (fb.active && fb.choice) {
  8514. \t\t\t\titems.push({
  8515. \t\t\t\t\tname:  (oi_data.fe_block && oi_data.fe_block.title) || 'ブロックの種類と段数',
  8516. \t\t\t\t\tvalue: fb.choice.label,
  8517. \t\t\t\t\tprice: fb.price,
  8518. \t\t\t\t\ton:    fb.choice.label,
  8519. \t\t\t\t\toff:   '',
  8520. \t\t\t\t});
  8521. \t\t\t\ttotal += fb.price;
  8522. \t\t\t}
  8523. \t\t\treturn { total: total, items: items };
  8524. \t\t}
  8525. \t\t/**
  8526. \t\t * free_area 1 エントリ ({w,d,h,m,c,price,unit_price,maker_price,ct,option1,option2})
  8527. \t\t * から sale_type 別に最終金額を算出する.
  8528. \t\t *
  8529. \t\t * 計算式(amount=1 ベース、出口で × 1.10 税込化):
  8530. \t\t *   1 通常        : price + ct + option_sum
  8531. \t\t *   2 補助金窓    : price × set_count + (ct + (set_count-1) × option2) + option_sum
  8532. \t\t *   3 物置        : (price + ct) × daisu + option_sum
  8533. \t\t *   4 フェンス    : price + (maisu-1) × unit_price
  8534. \t\t *                  + ct + max(0, maisu-3) × option1
  8535. \t\t *                  + option_sum   (maisu >= 3)
  8536. \t\t *   5 デッキ      : price + ct + option_sum   (area は表示用、計算非関与)
  8537. \t\t *   6 芝生        : price × ceil(area / (w_m × h_m)) + ct + option_sum
  8538. \t\t *   9 商品のみ    : price のみ(カート quantity 倍で総額)
  8539. \t\t *
  8540. \t\t * fe では option1 を ct_up、um では option2 を ct_up として転用.
  8541. \t\t * tf では w / h にロール幅・長さが格納されており parseLen で数値抽出.
  8542. \t\t *
  8543. \t\t * @param {Object} pp  free_area の 1 行(matrix エントリ)
  8544. \t\t * @param {number} optionTotal  collectOptions().total
  8545. \t\t * @param {Object} ctx  UI 入力 {set_count, daisu, maisu, area, quantityOnly, ...}
  8546. \t\t * @returns {Object} {goukei, price, ct, opt, qty}  すべて税込整数
  8547. \t\t */
  8548. \t\tfunction calcGoukei(pp, optionTotal, ctx) {
  8549. \t\t\tvar basePrice  = parseInt(pp.price)       || 0;
  8550. \t\t\tvar baseCt     = parseInt(pp.ct)          || 0;
  8551. \t\t\tvar unitPrice  = parseInt(pp.unit_price)  || 0;
  8552. \t\t\tvar optSum     = optionTotal;
  8553. \t\t\tvar price      = basePrice;
  8554. \t\t\tvar ct         = baseCt;
  8555. \t\t\tvar qty        = 1;
  8556. \t\t\tvar goukei     = 0;
  8557. \t\t\t// 「商品購入のみ」選択時は工事費・オプションをゼロにする(任意 sale_type で適用)
  8558. \t\t\tvar ops = [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10];
  8559. \t\t\tvar purchaseOnly = ops.some(function(v){ return v === '商品購入のみ'; });
  8560. \t\t\tif (purchaseOnly) {
  8561. \t\t\t\tbaseCt = 0;
  8562. \t\t\t\tct     = 0;
  8563. \t\t\t\toptSum = 0;
  8564. \t\t\t}
  8565. \t\t\tswitch (SALE_TYPE_ID) {
  8566. \t\t\t\tcase 2: {  // 補助金・窓 (シンプル表引き方式 2026-05-)
  8567. \t\t\t\t\t// 2026-05 仕様簡素化: 枚数軸を廃止し、subtype に枚数を内包.
  8568. \t\t\t\t\t// pp.price / pp.ct は (W, H, ガラス, subtype) の単一価格.
  8569. \t\t\t\t\t// 複数枚をまとめて買う場合はカート quantity で表現.
  8570. \t\t\t\t\tqty    = 1;
  8571. \t\t\t\t\tprice  = basePrice;
  8572. \t\t\t\t\tct     = baseCt;
  8573. \t\t\t\t\tgoukei = price + ct + optSum;
  8574. \t\t\t\t\tbreak;
  8575. \t\t\t\t}
  8576. \t\t\t\tcase 3: {  // 物置・ゴミステーション
  8577. \t\t\t\t\tqty   = Math.max(1, parseInt(ctx.daisu) || 1);
  8578. \t\t\t\t\tprice = basePrice * qty;
  8579. \t\t\t\t\tct    = baseCt * qty;
  8580. \t\t\t\t\tgoukei = price + ct + optSum;
  8581. \t\t\t\t\tbreak;
  8582. \t\t\t\t}
  8583. \t\t\t\tcase 4: {  // フェンス・組み立て式(maisu ≥ 3、base_amount = 3)
  8584. \t\t\t\t\t// scraper は amount=3 を base にしているので pp.price = price(3),
  8585. \t\t\t\t\t// pp.unit_price = price(4) - price(3).
  8586. \t\t\t\t\tqty   = Math.max(3, parseInt(ctx.maisu) || 3);
  8587. \t\t\t\t\tprice = basePrice + (qty - 3) * unitPrice;
  8588. \t\t\t\t\t// option1 が ct_up (4枚目以降の増分). 未設定なら ct 固定動作
  8589. \t\t\t\t\tvar ctUp1 = parseInt(pp.option1) || 0;
  8590. \t\t\t\t\tct = baseCt + Math.max(0, qty - 3) * ctUp1;
  8591. \t\t\t\t\t// fe_block(ブロック積み段数): collectOptions が base(3枚分)を optSum に
  8592. \t\t\t\t\t// 算入済み. ブロック費も本体同様に枚数連動するため、4枚目以降は 1枚毎に
  8593. \t\t\t\t\t// choice.unit_price(= block(4)-block(3)) を加算する.
  8594. \t\t\t\t\t// (顧客指摘「何枚施工でも増える金額が同じ」の是正。unit_price 未設定の
  8595. \t\t\t\t\t//  旧データでは +0 で従来動作。)
  8596. \t\t\t\t\tif (!purchaseOnly) {
  8597. \t\t\t\t\t\tvar fbC = collectFeBlock();
  8598. \t\t\t\t\t\tif (fbC.active && fbC.choice) {
  8599. \t\t\t\t\t\t\toptSum += Math.max(0, qty - 3) * (parseInt(fbC.choice.unit_price) || 0);
  8600. \t\t\t\t\t\t}
  8601. \t\t\t\t\t}
  8602. \t\t\t\t\tgoukei = price + ct + optSum;
  8603. \t\t\t\t\tbreak;
  8604. \t\t\t\t}
  8605. \t\t\t\tcase 5: {  // ウッドデッキ・タイルデッキ
  8606. \t\t\t\t\t// area は担当者向けの参考値として保持(計算には使わない)
  8607. \t\t\t\t\tqty    = 1;
  8608. \t\t\t\t\tgoukei = basePrice + baseCt + optSum;
  8609. \t\t\t\t\tprice  = basePrice;
  8610. \t\t\t\t\tct     = baseCt;
  8611. \t\t\t\t\tbreak;
  8612. \t\t\t\t}
  8613. \t\t\t\tcase 6: {  // 芝生・人工芝(ロール単位)
  8614. \t\t\t\t\t// pp.w \"1m\", pp.h \"10m\" から数値抽出
  8615. \t\t\t\t\tvar w_m = parseLen(pp.w);
  8616. \t\t\t\t\tvar h_m = parseLen(pp.h);
  8617. \t\t\t\t\tvar rollSize = w_m * h_m;
  8618. \t\t\t\t\tif (!rollSize || rollSize <= 0) rollSize = 1;
  8619. \t\t\t\t\t// 施工サイズ(面積)があれば必要枚数を自動算出。無ければ直接指定の枚数を使う。
  8620. \t\t\t\t\tvar area  = parseFloat(ctx.area) || 0;
  8621. \t\t\t\t\tif (area > 0) {
  8622. \t\t\t\t\t\tqty = Math.max(1, Math.ceil(area / rollSize));
  8623. \t\t\t\t\t} else {
  8624. \t\t\t\t\t\tqty = Math.max(1, parseInt(ctx.tf_qty) || 1);
  8625. \t\t\t\t\t}
  8626. \t\t\t\t\tprice  = basePrice * qty;
  8627. \t\t\t\t\tct     = baseCt;
  8628. \t\t\t\t\tgoukei = price + ct + optSum;
  8629. \t\t\t\t\tbreak;
  8630. \t\t\t\t}
  8631. \t\t\t\tcase 7: {  // 数量買い・基本工事費固定(gf ガーデンファニチャー / st 石材)
  8632. \t\t\t\t\tqty    = Math.max(1, parseInt(ctx.suuryou) || 1);
  8633. \t\t\t\t\tprice  = basePrice * qty;
  8634. \t\t\t\t\tct     = baseCt;                 // ct は固定(数量に依らない)
  8635. \t\t\t\t\tgoukei = price + ct + optSum;
  8636. \t\t\t\t\tbreak;
  8637. \t\t\t\t}
  8638. \t\t\t\tcase 9: {  // 商品のみ購入
  8639. \t\t\t\t\t// カート側で quantity × unit price するため goukei は単品価格
  8640. \t\t\t\t\tqty    = parseInt(ctx.quantityOnly) || 1;
  8641. \t\t\t\t\tprice  = basePrice;
  8642. \t\t\t\t\tct     = 0;
  8643. \t\t\t\t\toptSum = 0;
  8644. \t\t\t\t\tgoukei = price;
  8645. \t\t\t\t\tbreak;
  8646. \t\t\t\t}
  8647. \t\t\t\tdefault: {  // 1: 通常(カーポート等、matrix 選択のみ)
  8648. \t\t\t\t\tqty    = 1;
  8649. \t\t\t\t\tgoukei = basePrice + baseCt + optSum;
  8650. \t\t\t\t\tbreak;
  8651. \t\t\t\t}
  8652. \t\t\t}
  8653. \t\t\t// 出口で税込化(pp.price/pp.ct/op_data.price はすべて税抜で保存されている前提)
  8654. \t\t\treturn {
  8655. \t\t\t\tgoukei: toIncTax(goukei),
  8656. \t\t\t\tprice:  toIncTax(price),
  8657. \t\t\t\tct:     toIncTax(ct),
  8658. \t\t\t\topt:    toIncTax(optSum),
  8659. \t\t\t\tqty:    qty,
  8660. \t\t\t};
  8661. \t\t}
  8662. \t\t/**
  8663. \t\t * 寸法文字列から「メートル単位の数値」を抽出する.
  8664. \t\t *
  8665. \t\t * 単位は m / cm / mm を認識し、いずれも m 単位に正規化して返す.
  8666. \t\t * 単位が無い場合は m 単位とみなす(旧 tf データ \"1m\" \"10m\" との互換).
  8667. \t\t * 数値が見つからない場合は 0 を返す(呼び出し側で fallback).
  8668. \t\t *
  8669. \t\t * 例:
  8670. \t\t *   \"1m\"     → 1
  8671. \t\t *   \"100cm\"  → 1   (2026-06 以降の m → cm 正規化に対応)
  8672. \t\t *   \"200cm\"  → 2
  8673. \t\t *   \"5.5m\"   → 5.5
  8674. \t\t *   \"1000mm\" → 1
  8675. \t\t *   \"\"       → 0
  8676. \t\t */
  8677. \t\tfunction parseLen(s) {
  8678. \t\t\tif (!s) return 0;
  8679. \t\t\tvar str = String(s);
  8680. \t\t\tvar m = str.match(/(\\d+(?:\\.\\d+)?)\\s*(mm|cm|m)?/i);
  8681. \t\t\tif (!m) return 0;
  8682. \t\t\tvar n = parseFloat(m[1]);
  8683. \t\t\tif (isNaN(n)) return 0;
  8684. \t\t\tvar unit = (m[2] || 'm').toLowerCase();
  8685. \t\t\tif (unit === 'cm') return n / 100;
  8686. \t\t\tif (unit === 'mm') return n / 1000;
  8687. \t\t\treturn n;  // 'm' or no unit
  8688. \t\t}
  8689. \t\t// pp は autoSelectFirstColor 等からも参照するので global にする
  8690. \t\tvar pp = {{ pp|raw }};
  8691. \t\t// sale_type=2 の幅 / 高さ ladder (Twig p_w / p_h を JS で参照するため).
  8692. \t\t// 入力 mm 値を pp の幅・高さバケット文字列にマッピングする際の元データ.
  8693. \t\t// p_w / p_h は連想配列で来ることがあるため Object.values で配列化する.
  8694. \t\tvar PP_W_LADDER = Object.values({{ p_w|default({})|json_encode|raw }} || {});
  8695. \t\tvar PP_H_LADDER = Object.values({{ p_h|default({})|json_encode|raw }} || {});
  8696. \t\t/* ============================================================
  8697. \t\t   sale_type=2 (補助金窓) 専用: 複数タイプ集計 & 補助金計算
  8698. \t\t   ============================================================
  8699. \t\t   - 入力 UI: #window-types-container 配下の .window-type-block
  8700. \t\t   - 補助金根拠: 先進的窓リノベ2026事業
  8701. \t\t     https://window-renovation2026.env.go.jp/construction/inner-window.html
  8702. \t\t   - 価格軸: (subtype, w, h, glass, color) で pp を lookup
  8703. \t\t   - 1 商品 = 1 明細 にまとめ、内訳 JSON を別途保存予定 (cart 連携は後続タスク)
  8704. \t\t   ============================================================ */
  8705. \t\t// 補助金マトリクス: [住宅区分][性能][サイズ区分] → 1 箇所あたり金額 (税抜・端数なし)
  8706. \t\tvar WINDOW_SUBSIDY_MATRIX = {
  8707. \t\t\tdetached:  { // 戸建住宅・延床240㎡以下の非住宅
  8708. \t\t\t\tP: { G: 140000, L: 89000, M: 58000, S: 36000 },
  8709. \t\t\t\tS: { G: 76000,  L: 52000, M: 34000, S: 22000 }
  8710. \t\t\t},
  8711. \t\t\tapartment: { // 低層・中高層集合住宅・240㎡超の非住宅
  8712. \t\t\t\tP: { G: 152000, L: 98000, M: 64000, S: 40000 },
  8713. \t\t\t\tS: { G: 83000,  L: 57000, M: 37000, S: 24000 }
  8714. \t\t\t}
  8715. \t\t};
  8716. \t\t// 住宅区分: 画面 UI (input[name=\"window_housing_type\"]) から取得する.
  8717. \t\t// 既定値は PFC meta_key=\"住宅区分\" を fallback (未設定なら '戸建').
  8718. \t\tvar HOUSING_TYPE_DEFAULT = {{ getProduct_field(Product.id, '住宅区分')|default('戸建')|json_encode|raw }};
  8719. \t\tfunction getCurrentHousingKey() {
  8720. \t\t\tvar el = document.querySelector('input[name=\"window_housing_type\"]:checked');
  8721. \t\t\tvar v  = el ? el.value : HOUSING_TYPE_DEFAULT;
  8722. \t\t\treturn (v === '集合住宅') ? 'apartment' : 'detached';
  8723. \t\t}
  8724. \t\t// 商品シリーズ自動判定 (Product.name から)
  8725. \t\t// 根拠カタログ: YKK AP「ウチリモ」XAAAA-H26-067-1 (2026.04), 同「LiteU」XAAAA-H16-088-2,
  8726. \t\t//              三協アルミ「プラメイクEII」0142_STJ1931L, LIXIL「インプラス」(既知)
  8727. \t\tvar PRODUCT_NAME_RAW = {{ Product.name|default('')|json_encode|raw }};
  8728. \t\tfunction detectProductSeries(name) {
  8729. \t\t\tif (!name) return null;
  8730. \t\t\tif (/ウチリモ/.test(name)) return 'uchirimo';
  8731. \t\t\tif (/プラマード\\s*U/i.test(name)) return 'pramado_u';
  8732. \t\t\tif (/インプラス/.test(name)) return 'inplus';
  8733. \t\t\tif (/プラメイク\\s*EII|プラメイクEII/i.test(name)) return 'plamake_eii';
  8734. \t\t\tif (/LiteU/i.test(name)) return 'lite_u';
  8735. \t\t\treturn null;
  8736. \t\t}
  8737. \t\t// シリーズ上限グレード:
  8738. \t\t//   'P'  = SS/P まで到達可能 (真空断熱ガラス採用シリーズ)
  8739. \t\t//   'S'  = Low-E 複層止まり (真空断熱ガラスのラインなし)
  8740. \t\t//   null = 単板のみ → 補助金対象外
  8741. \t\tvar SERIES_GRADE_CAP = {
  8742. \t\t\tuchirimo:    'P',
  8743. \t\t\tpramado_u:   'P',
  8744. \t\t\tinplus:      'S',
  8745. \t\t\tplamake_eii: 'S',
  8746. \t\t\tlite_u:      null
  8747. \t\t};
  8748. \t\tvar DETECTED_SERIES = detectProductSeries(PRODUCT_NAME_RAW);
  8749. \t\tvar SERIES_GRADE_CAP_VAL = (DETECTED_SERIES !== null && Object.prototype.hasOwnProperty.call(SERIES_GRADE_CAP, DETECTED_SERIES))
  8750. \t\t\t? SERIES_GRADE_CAP[DETECTED_SERIES]
  8751. \t\t\t: undefined;
  8752. \t\t// 商品単位グレード上限 (PFC `meta_key=補助金グレード上限` で個別上書き)
  8753. \t\t// 値: 'P' / 'SS' / 'S' / '対象外' / '無' / 'NONE' / 空文字 (未指定)
  8754. \t\tvar PRODUCT_GRADE_CAP_RAW = {{ getProduct_field(Product.id, '補助金グレード上限')|default('')|json_encode|raw }};
  8755. \t\tfunction normalizeGradeCap(v) {
  8756. \t\t\tif (v === null || v === undefined || v === '') return undefined;
  8757. \t\t\tvar s = String(v).trim().toUpperCase();
  8758. \t\t\tif (s === 'NONE' || s === '対象外' || s === '無') return null;
  8759. \t\t\tif (s === 'P' || s === 'SS') return 'P';
  8760. \t\t\tif (s === 'S') return 'S';
  8761. \t\t\treturn undefined;
  8762. \t\t}
  8763. \t\tvar PRODUCT_GRADE_CAP = normalizeGradeCap(PRODUCT_GRADE_CAP_RAW);
  8764. \t\t// 窓種 (subtype = option1) ごとのグレード上限.
  8765. \t\t// 根拠: YKK AP「ウチリモ」業務用 (XAAAA-H26-067-1) の窓種別ラインナップで
  8766. \t\t//      真空ガラス (Glavenir) の設定有無を確認:
  8767. \t\t//        引違い窓 (2/3/4枚建) / 浴室仕様 引違い窓 / FIX窓        → P 到達可能
  8768. \t\t//        内開き窓 (居室/浴室) / 開き窓テラス / テラスドア類       → 真空ガラスなし → S 止まり
  8769. \t\tfunction detectSubtypeGradeCap(subtype) {
  8770. \t\t\tif (!subtype) return undefined;
  8771. \t\t\tvar s = String(subtype);
  8772. \t\t\tif (/内開|開き窓テラス|テラスドア|開き戸/.test(s)) return 'S';
  8773. \t\t\treturn undefined;
  8774. \t\t}
  8775. \t\t// クリップ: 強さは 'P' > 'S' > null (対象外). cap=null は強制対象外, cap=undefined は無効化なし.
  8776. \t\tfunction clipGradeBy(grade, cap) {
  8777. \t\t\tif (cap === undefined) return grade;
  8778. \t\t\tif (cap === null)      return null;
  8779. \t\t\tif (grade === null)    return null;
  8780. \t\t\tif (cap === 'S' && grade === 'P') return 'S';
  8781. \t\t\treturn grade;
  8782. \t\t}
  8783. \t\tfunction finalizeGlassGrade(raw, subtype) {
  8784. \t\t\tvar g = clipGradeBy(raw, SERIES_GRADE_CAP_VAL);
  8785. \t\t\tg     = clipGradeBy(g,   detectSubtypeGradeCap(subtype));
  8786. \t\t\tg     = clipGradeBy(g,   PRODUCT_GRADE_CAP);
  8787. \t\t\treturn g;
  8788. \t\t}
  8789. \t\t/**
  8790. \t\t * ガラスタイプ名から性能区分 'P' (SS, Uw≤1.1) / 'S' (Uw≤1.5) / null を判別.
  8791. \t\t * null = 補助対象外.
  8792. \t\t *
  8793. \t\t * 根拠: YKK AP「ウチリモ 内窓」業務用カタログ (XAAAA-H26-069-1) で
  8794. \t\t *       P (SS) は真空断熱ガラスのみ、Low-E はアルゴン入りでも S 止まり、
  8795. \t\t *       Low-E ガス無 + 型ガラス / フロストは 2026年4月で対象外、
  8796. \t\t *       が確認できた。アルゴン入り Low-E を P 判定する旧ルールは誤りだった。
  8797. \t\t *
  8798. \t\t * シリーズによっては P がそもそも存在しない (LIXIL インプラスは S 一律)
  8799. \t\t * ため、最終的には PFC で商品単位の上限を上書きできる仕組みが必要。
  8800. \t\t */
  8801. \t\tfunction detectGlassPerformance(glassName) {
  8802. \t\t\tif (!glassName) return null;
  8803. \t\t\tvar n = String(glassName);
  8804. \t\t\t// 補助対象外: 単板 / 和紙調 / 防音 / 防犯 / 型ガラス・フロスト (Low-E ガス無の型は 2026/4 で対象外)
  8805. \t\t\tif (/単ガラス|単板|和紙調|防音|防犯|複層\\/型|型ガラス|フロスト/.test(n)) return null;
  8806. \t\t\t// P (SS): 真空断熱ガラスのみ
  8807. \t\t\tif (/真空断熱/.test(n)) return 'P';
  8808. \t\t\t// S: Low-E 系のみ (アルゴン入りでも S 止まり)
  8809. \t\t\tif (/Low-?E/i.test(n)) return 'S';
  8810. \t\t\t// 一般複層 / ブラインドイン複層 / 複層強化 など Low-E 無しの複層は補助対象外
  8811. \t\t\treturn null;
  8812. \t\t}
  8813. \t\t/**
  8814. \t\t * 幅 mm × 高さ mm からサイズ区分 'G' (≥4.0㎡) / 'L' (2.8-3.9) / 'M' (1.6-2.7) / 'S' (0.2-1.5) / null.
  8815. \t\t * null = 補助対象外 (0.2㎡ 未満).
  8816. \t\t */
  8817. \t\tfunction detectSizeClass(w_mm, h_mm) {
  8818. \t\t\tvar w = parseFloat(w_mm) || 0;
  8819. \t\t\tvar h = parseFloat(h_mm) || 0;
  8820. \t\t\tif (w <= 0 || h <= 0) return null;
  8821. \t\t\tvar area = (w * h) / 1000000.0;
  8822. \t\t\tif (area < 0.2) return null;
  8823. \t\t\tif (area < 1.6) return 'S';
  8824. \t\t\tif (area < 2.8) return 'M';
  8825. \t\t\tif (area < 4.0) return 'L';
  8826. \t\t\treturn 'G';
  8827. \t\t}
  8828. \t\tfunction lookupSubsidyAmount(performance, sizeClass) {
  8829. \t\t\tif (!performance || !sizeClass) return 0;
  8830. \t\t\tvar t = WINDOW_SUBSIDY_MATRIX[getCurrentHousingKey()];
  8831. \t\t\tif (!t || !t[performance]) return 0;
  8832. \t\t\treturn t[performance][sizeClass] || 0;
  8833. \t\t}
  8834. \t\t/**
  8835. \t\t * mm 入力値を ladder バケット文字列に変換する.
  8836. \t\t *   bucketizeMm(1750, [\"100cm まで\",\"150cm まで\",\"200cm まで\",\"300cm まで\"]) → \"200cm まで\"
  8837. \t\t * - 入力が空 or 0 のときはそのまま返す (未入力扱い)
  8838. \t\t * - 入力がラダー最大を超えるときは最大バケットを返す (= 価格上限の保護)
  8839. \t\t * - 入力文字列が既にラダーラベルそのものなら無変換 (互換のため)
  8840. \t\t */
  8841. \t\tfunction bucketizeMm(input, ladder) {
  8842. \t\t\tif (!input && input !== 0) return '';
  8843. \t\t\tif (!ladder || ladder.length === 0) return input;
  8844. \t\t\tvar s = String(input).trim();
  8845. \t\t\tif (s === '') return '';
  8846. \t\t\tif (ladder.indexOf(s) >= 0) return s;
  8847. \t\t\tvar mm = parseMm(s);
  8848. \t\t\tif (mm <= 0) return s;
  8849. \t\t\tvar withMax = ladder.map(function(b) { return { label: b, max: parseMm(b) }; });
  8850. \t\t\twithMax.sort(function(a, b) { return a.max - b.max; });
  8851. \t\t\tfor (var i = 0; i < withMax.length; i++) {
  8852. \t\t\t\tif (mm <= withMax[i].max) return withMax[i].label;
  8853. \t\t\t}
  8854. \t\t\treturn withMax[withMax.length - 1].label;
  8855. \t\t}
  8856. \t\t/**
  8857. \t\t * pp 配列から該当 1 行を返す. 完全一致優先、見つからなければ最初の候補.
  8858. \t\t * 軸: subtype (option1) / w / h / m / c. axisMatch は既存ロジックと同じ.
  8859. \t\t * sale_type=2 では pw_val / ph_val に mm 数値が来るため、内部で bucketizeMm
  8860. \t\t * を通してから既存マッチングに渡す.
  8861. \t\t */
  8862. \t\tfunction lookupPpRow(subtype, pw_val, ph_val, pm_val, pc_val) {
  8863. \t\t\tif (!pp || pp.length === 0) return null;
  8864. \t\t\tvar pw_bucket = bucketizeMm(pw_val, PP_W_LADDER);
  8865. \t\t\tvar ph_bucket = bucketizeMm(ph_val, PP_H_LADDER);
  8866. \t\t\tvar axMatch = function(input, value) {
  8867. \t\t\t\treturn input == value || input === '指定なし' || value === '' || value == null;
  8868. \t\t\t};
  8869. \t\t\tvar colMatch = function(input, value) {
  8870. \t\t\t\tif (axMatch(input, value)) return true;
  8871. \t\t\t\tif (typeof value === 'string' && value.indexOf('/') !== -1 && input) {
  8872. \t\t\t\t\treturn value.split('/').some(function(s) { return s.trim() === input; });
  8873. \t\t\t\t}
  8874. \t\t\t\treturn false;
  8875. \t\t\t};
  8876. \t\t\tvar candidates = pp.filter(function(el) {
  8877. \t\t\t\treturn axMatch(pw_bucket, el.w)
  8878. \t\t\t\t\t&& axMatch(ph_bucket, el.h)
  8879. \t\t\t\t\t&& axMatch(pm_val, el.m)
  8880. \t\t\t\t\t&& axMatch(subtype, el.option1);
  8881. \t\t\t});
  8882. \t\t\tfor (var i = 0; i < candidates.length; i++) {
  8883. \t\t\t\tif (colMatch(pc_val, candidates[i].c)) return candidates[i];
  8884. \t\t\t}
  8885. \t\t\treturn candidates[0] || null;
  8886. \t\t}
  8887. \t\t/**
  8888. \t\t * \"1000mm\" / \"200cm\" / \"1.0m\" / 単位なし → mm に正規化して返す.
  8889. \t\t * UI 上の「200cm まで」等の文字列をそのまま渡せるようにする.
  8890. \t\t */
  8891. \t\tfunction parseMm(s) {
  8892. \t\t\tif (!s) return 0;
  8893. \t\t\tvar str = String(s);
  8894. \t\t\tvar m = str.match(/(\\d+(?:\\.\\d+)?)/);
  8895. \t\t\tif (!m) return 0;
  8896. \t\t\tvar num = parseFloat(m[1]);
  8897. \t\t\tif (/mm/i.test(str)) return num;
  8898. \t\t\tif (/cm/i.test(str)) return num * 10;
  8899. \t\t\tif (/(^|\\d)\\s*m(\$|\\W)/i.test(str)) return num * 1000;
  8900. \t\t\treturn num;
  8901. \t\t}
  8902. \t\t/**
  8903. \t\t * 1 タイプブロックから入力を読み、pp lookup → 単価・補助金額を計算して返す.
  8904. \t\t * incomplete=true: 軸のどれかが未選択 → 計算しない (UI で「未選択」を示すため).
  8905. \t\t */
  8906. \t\tfunction collectWindowTypeRow(block) {
  8907. \t\t\tvar get = function(axis) {
  8908. \t\t\t\t// radio / checkbox は :checked、それ以外 (number/text) は値そのまま.
  8909. \t\t\t\tvar radio = block.querySelector('input[data-axis=\"' + axis + '\"]:checked');
  8910. \t\t\t\tif (radio) return radio.value;
  8911. \t\t\t\tvar any = block.querySelector('input[data-axis=\"' + axis + '\"]');
  8912. \t\t\t\tif (!any) return '';
  8913. \t\t\t\tif (any.type === 'radio' || any.type === 'checkbox') return '';
  8914. \t\t\t\treturn (any.value || '').trim();
  8915. \t\t\t};
  8916. \t\t\tvar setqtyEl = block.querySelector('input[data-axis=\"setqty\"]');
  8917. \t\t\tvar subtype = get('subtype');
  8918. \t\t\tvar pw_val  = get('pw');
  8919. \t\t\tvar ph_val  = get('ph');
  8920. \t\t\tvar pm_val  = get('pm');
  8921. \t\t\tvar pc_val  = get('pc');
  8922. \t\t\tvar setqty  = setqtyEl ? Math.max(1, parseInt(setqtyEl.value) || 1) : 1;
  8923. \t\t\tvar row = {
  8924. \t\t\t\tsubtype: subtype, pw: pw_val, ph: ph_val, pm: pm_val, pc: pc_val, setqty: setqty,
  8925. \t\t\t\tunit_price_exc: 0, unit_ct_exc: 0, subsidy: 0,
  8926. \t\t\t\tsize_class: null, glass_perf: null,
  8927. \t\t\t\tincomplete: false
  8928. \t\t\t};
  8929. \t\t\t// p_option1 / p_w / p_h / p_m / color のいずれかが商品データに無いときは未選択でも完了扱いにする.
  8930. \t\t\t// (例: 商品によっては subtype が無い場合がある)
  8931. \t\t\tvar hasSubtype = !!block.querySelector('input[data-axis=\"subtype\"]');
  8932. \t\t\tvar hasPw      = !!block.querySelector('input[data-axis=\"pw\"]');
  8933. \t\t\tvar hasPh      = !!block.querySelector('input[data-axis=\"ph\"]');
  8934. \t\t\tvar hasPm      = !!block.querySelector('input[data-axis=\"pm\"]');
  8935. \t\t\tvar hasPc      = !!block.querySelector('input[data-axis=\"pc\"]');
  8936. \t\t\tif ((hasSubtype && !subtype) || (hasPw && !pw_val) || (hasPh && !ph_val)
  8937. \t\t\t    || (hasPm && !pm_val)  || (hasPc && !pc_val)) {
  8938. \t\t\t\trow.incomplete = true;
  8939. \t\t\t\treturn row;
  8940. \t\t\t}
  8941. \t\t\tvar ppRow = lookupPpRow(subtype, pw_val, ph_val, pm_val, pc_val);
  8942. \t\t\tif (ppRow) {
  8943. \t\t\t\trow.unit_price_exc = parseInt(ppRow.price) || 0;
  8944. \t\t\t\trow.unit_ct_exc    = parseInt(ppRow.ct)    || 0;
  8945. \t\t\t}
  8946. \t\t\t// ガラス名検出 → シリーズ上限 → subtype 上限 → 商品上限 の順で min クリップ.
  8947. \t\t\t// 例: LiteU (SERIES_GRADE_CAP_VAL=null) は Low-E でも null に落ちて補助対象外.
  8948. \t\t\t// 例: ウチリモの「内開き窓」subtype は真空ガラスでも S に落ちる.
  8949. \t\t\trow.glass_perf = finalizeGlassGrade(detectGlassPerformance(pm_val), subtype);
  8950. \t\t\trow.size_class = detectSizeClass(parseMm(pw_val), parseMm(ph_val));
  8951. \t\t\trow.subsidy    = lookupSubsidyAmount(row.glass_perf, row.size_class);
  8952. \t\t\treturn row;
  8953. \t\t}
  8954. \t\t/**
  8955. \t\t * sale_type=2 用集計: 全タイプから合計を出し DOM 更新.
  8956. \t\t * 計算式 (税抜→税込で出口で 1.10 倍):
  8957. \t\t *   商品金額 = Σ(各タイプ単価 × set_qty)
  8958. \t\t *   基本工事費 = 1 回分 (各タイプ pp.ct のうち最初に得た非ゼロ値)
  8959. \t\t *   補助金合計 = Σ(各タイプ補助金 × set_qty)
  8960. \t\t *   実質支払額 = (商品+ct+option) 税込 - 補助金合計
  8961. \t\t */
  8962. \t\tfunction recalcAllForSaleType2() {
  8963. \t\t\tif (typeof SALE_TYPE_ID === 'undefined' || SALE_TYPE_ID != 2) return;
  8964. \t\t\tif (!pp || pp.length === 0) {
  8965. \t\t\t\t\$('#mitsumori_message').text('価格データ準備中');
  8966. \t\t\t\t\$('#mitsumori_btn').hide();
  8967. \t\t\t\t['#mitsumori_goukei','#mitsumori_off','#mitsumori_price','#maker_price',
  8968. \t\t\t\t '#mitsumori_ct','#mitsumori_option','#mitsumori_kei','#mitsumori_shoukei','#mitsumori_tax']
  8969. \t\t\t\t .forEach(function(s){ \$(s).text('---円'); });
  8970. \t\t\t\treturn;
  8971. \t\t\t}
  8972. \t\t\tvar blocks = document.querySelectorAll('#window-types-container .window-type-block');
  8973. \t\t\tif (blocks.length === 0) return;
  8974. \t\t\tvar rows = [];
  8975. \t\t\tvar hasIncomplete = false;
  8976. \t\t\tvar baseCt = 0;
  8977. \t\t\tvar hasAnyPriced = false;
  8978. \t\t\tblocks.forEach(function(b) {
  8979. \t\t\t\tvar r = collectWindowTypeRow(b);
  8980. \t\t\t\trows.push({ block: b, row: r });
  8981. \t\t\t\tif (r.incomplete) hasIncomplete = true;
  8982. \t\t\t\tif (r.unit_ct_exc > 0 && baseCt === 0) baseCt = r.unit_ct_exc;
  8983. \t\t\t\tif (r.unit_price_exc > 0) hasAnyPriced = true;
  8984. \t\t\t\tvar subSpan = b.querySelector('.wt-subsidy-amount');
  8985. \t\t\t\tif (subSpan) subSpan.textContent = r.incomplete ? '―' : Math.round(r.subsidy * r.setqty).toLocaleString();
  8986. \t\t\t});
  8987. \t\t\tif (hasIncomplete || !hasAnyPriced) {
  8988. \t\t\t\t\$('#mitsumori_message').text('窓タイプを選択してください');
  8989. \t\t\t\t\$('#mitsumori_btn').hide();
  8990. \t\t\t\treturn;
  8991. \t\t\t}
  8992. \t\t\tvar ops = [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10];
  8993. \t\t\tvar purchaseOnly = ops.some(function(v){ return v === '商品購入のみ'; });
  8994. \t\t\tvar sumPriceExc = 0, sumSubsidy = 0, totalPanes = 0;
  8995. \t\t\trows.forEach(function(item) {
  8996. \t\t\t\tvar r = item.row;
  8997. \t\t\t\tsumPriceExc += r.unit_price_exc * r.setqty;
  8998. \t\t\t\tsumSubsidy  += r.subsidy * r.setqty;
  8999. \t\t\t\tif (r.unit_price_exc > 0) totalPanes += r.setqty;
  9000. \t\t\t});
  9001. \t\t\t// 内窓 工事費(顧客最終回答): 1枚目 22,000円 + 2枚目以降 1枚あたり +5,000円(税込表示額)。
  9002. \t\t\t// 既存パイプライン整合のため税抜(ctExc)も用意(税行 taxAmt 用)。商品購入のみは 0。
  9003. \t\t\tvar WINDOW_CT_BASE = 22000, WINDOW_CT_ADD = 5000;
  9004. \t\t\tvar ctIncTarget = purchaseOnly ? 0 : (WINDOW_CT_BASE + Math.max(0, totalPanes - 1) * WINDOW_CT_ADD);
  9005. \t\t\tvar ctExc  = purchaseOnly ? 0 : Math.round(ctIncTarget / (1 + TAX_RATE));
  9006. \t\t\tvar optExc = purchaseOnly ? 0 : (collectOptions().total || 0);
  9007. \t\t\tvar sumPriceInc = Math.round(sumPriceExc * (1 + TAX_RATE));
  9008. \t\t\tvar ctInc       = ctIncTarget;
  9009. \t\t\tvar optInc      = Math.round(optExc * (1 + TAX_RATE));
  9010. \t\t\tvar goukeiInc   = sumPriceInc + ctInc + optInc;
  9011. \t\t\t// 窓リノベ2026 申請条件:
  9012. \t\t\t//   - 補助金合計 ≥ 50,000 円 (5 万円未満は申請不可 → 還元 0 円扱い)
  9013. \t\t\t//   - 1 戸あたり上限 1,000,000 円 (住宅・非住宅240㎡以下)
  9014. \t\t\t//     ※ 非住宅 240㎡超の 10,000,000 円上限は対象外 (商品設計時に別扱い想定)
  9015. \t\t\tvar SUBSIDY_MIN_AMOUNT = 50000;
  9016. \t\t\tvar SUBSIDY_MAX_PER_UNIT = 1000000;
  9017. \t\t\tvar subsidyRawSum = sumSubsidy;
  9018. \t\t\tvar subsidyEligible = subsidyRawSum >= SUBSIDY_MIN_AMOUNT;
  9019. \t\t\tvar subsidyAmt = 0;
  9020. \t\t\tvar subsidyNote = '';
  9021. \t\t\tif (subsidyEligible) {
  9022. \t\t\t\tif (subsidyRawSum > SUBSIDY_MAX_PER_UNIT) {
  9023. \t\t\t\t\tsubsidyAmt = SUBSIDY_MAX_PER_UNIT;
  9024. \t\t\t\t\tsubsidyNote = '※補助上限 ' + SUBSIDY_MAX_PER_UNIT.toLocaleString()
  9025. \t\t\t\t\t\t+ '円 超過分は控除対象外(補助金合計 ' + subsidyRawSum.toLocaleString() + '円)';
  9026. \t\t\t\t} else {
  9027. \t\t\t\t\tsubsidyAmt = subsidyRawSum;
  9028. \t\t\t\t}
  9029. \t\t\t} else if (subsidyRawSum > 0) {
  9030. \t\t\t\tsubsidyNote = '※補助金合計が 5 万円未満のため申請対象外です('
  9031. \t\t\t\t\t+ subsidyRawSum.toLocaleString() + '円)';
  9032. \t\t\t} else if (SERIES_GRADE_CAP_VAL === null) {
  9033. \t\t\t\t// LiteU 等の単板構成シリーズ: グレード判定で必ず null になる
  9034. \t\t\t\tsubsidyNote = '※本商品は補助金(先進的窓リノベ2026事業)対象外です';
  9035. \t\t\t} else if (PRODUCT_GRADE_CAP === null) {
  9036. \t\t\t\tsubsidyNote = '※本商品は補助金対象外として登録されています';
  9037. \t\t\t}
  9038. \t\t\tvar implementedInc = Math.max(0, goukeiInc - subsidyAmt);
  9039. \t\t\tvar taxAmt      = Math.round((sumPriceExc + ctExc + optExc) * TAX_RATE);
  9040. \t\t\t\$('#mitsumori_message').text(subsidyNote);
  9041. \t\t\t\$('#mitsumori_btn').show();
  9042. \t\t\t\$('#mitsumori_goukei').text(goukeiInc.toLocaleString() + '円');
  9043. \t\t\t\$('#mitsumori_price').text(sumPriceInc.toLocaleString() + '円');
  9044. \t\t\t\$('#mitsumori_ct').text(ctInc.toLocaleString() + '円');
  9045. \t\t\t\$('#mitsumori_option').text(optInc.toLocaleString() + '円');
  9046. \t\t\t\$('#mitsumori_off').text((subsidyAmt > 0 ? '-' : '') + subsidyAmt.toLocaleString() + '円');
  9047. \t\t\t\$('#maker_price').text('---円'); // 補助金窓では未使用
  9048. \t\t\t\$('#mitsumori_kei').text(goukeiInc.toLocaleString() + '円');
  9049. \t\t\t\$('#mitsumori_shoukei').text(implementedInc.toLocaleString() + '円');
  9050. \t\t\t\$('#mitsumori_tax').text(taxAmt.toLocaleString() + '円');
  9051. \t\t\t// 内訳を mitsumori_json に詰めて hidden input にセット (PDF / カート連携用)
  9052. \t\t\tvar window_types = rows.map(function(item) {
  9053. \t\t\t\tvar r = item.row;
  9054. \t\t\t\t// 幅 / 高さは数値入力 (mm) が来るので \"1750mm\" 形式で保存する.
  9055. \t\t\t\t// 古い radio 由来の \"200cm まで\" 形式が来た場合はそのまま保存して互換.
  9056. \t\t\t\tvar w_mm = parseMm(r.pw);
  9057. \t\t\t\tvar h_mm = parseMm(r.ph);
  9058. \t\t\t\tvar w_save = (w_mm > 0 && /^\\s*\\d+(?:\\.\\d+)?\\s*\$/.test(String(r.pw))) ? (w_mm + 'mm') : r.pw;
  9059. \t\t\t\tvar h_save = (h_mm > 0 && /^\\s*\\d+(?:\\.\\d+)?\\s*\$/.test(String(r.ph))) ? (h_mm + 'mm') : r.ph;
  9060. \t\t\t\treturn {
  9061. \t\t\t\t\tsubtype:        r.subtype,
  9062. \t\t\t\t\tw:              w_save,
  9063. \t\t\t\t\th:              h_save,
  9064. \t\t\t\t\tglass:          r.pm,
  9065. \t\t\t\t\tcolor:          r.pc,
  9066. \t\t\t\t\tsetqty:         r.setqty,
  9067. \t\t\t\t\tunit_price_inc: Math.round(r.unit_price_exc * (1 + TAX_RATE)),
  9068. \t\t\t\t\tline_total_inc: Math.round(r.unit_price_exc * r.setqty * (1 + TAX_RATE)),
  9069. \t\t\t\t\tsize_class:     r.size_class,
  9070. \t\t\t\t\tglass_perf:     r.glass_perf,
  9071. \t\t\t\t\tsubsidy_unit:   r.subsidy,
  9072. \t\t\t\t\tsubsidy_total:  r.subsidy * r.setqty
  9073. \t\t\t\t};
  9074. \t\t\t});
  9075. \t\t\tvar opCalc2 = collectOptions();
  9076. \t\t\tvar mitsumori_json = {
  9077. \t\t\t\t\"mitsumori_goukei\": goukeiInc.toLocaleString() + '円',
  9078. \t\t\t\t\"mitsumori_price\":  sumPriceInc.toLocaleString() + '円',
  9079. \t\t\t\t\"mitsumori_ct\":     ctInc.toLocaleString() + '円',
  9080. \t\t\t\t\"mitsumori_option\": optInc.toLocaleString() + '円',
  9081. \t\t\t\t\"mitsumori_off\":    (subsidyAmt > 0 ? '-' : '') + subsidyAmt.toLocaleString() + '円',
  9082. \t\t\t\t\"maker_price\":      '---円',
  9083. \t\t\t\t\"product_id\":       {{ Product.id }},
  9084. \t\t\t\t\"sale_type\":        SALE_TYPE_ID,
  9085. \t\t\t\t\"housing_key\":      getCurrentHousingKey(),
  9086. \t\t\t\t\"series_key\":       DETECTED_SERIES,
  9087. \t\t\t\t\"series_grade_cap\": (SERIES_GRADE_CAP_VAL === undefined) ? null : SERIES_GRADE_CAP_VAL,
  9088. \t\t\t\t\"product_grade_cap\":(PRODUCT_GRADE_CAP    === undefined) ? null : PRODUCT_GRADE_CAP,
  9089. \t\t\t\t\"window_types\":     window_types,
  9090. \t\t\t\t\"subsidy_total\":    subsidyAmt,
  9091. \t\t\t\t\"subsidy_raw\":      subsidyRawSum,
  9092. \t\t\t\t\"subsidy_eligible\": subsidyEligible,
  9093. \t\t\t\t\"subsidy_note\":     subsidyNote,
  9094. \t\t\t\t\"op_items\":         opCalc2.items
  9095. \t\t\t};
  9096. \t\t\t\$('#mitsumori_json').val(JSON.stringify(mitsumori_json));
  9097. \t\t\trenderWindowTypesModalRows(window_types, subsidyAmt);
  9098. \t\t}
  9099. \t\t/**
  9100. \t\t * sale_type=2 用: 見積モーダル明細テーブルを window_types で動的展開.
  9101. \t\t * - 既存の商品名行 (1 行目) は hide() し、各タイプ行を上に挿入
  9102. \t\t * - 基本工事費行はそのまま (#mitsumori_ct_01 / _02 が更新されている)
  9103. \t\t * - 補助金 (割引額) 行を末尾に追加
  9104. \t\t * - 既存の renderOptionDetailRows と共存できるよう class で区別
  9105. \t\t */
  9106. \t\tfunction renderWindowTypesModalRows(window_types, subsidyAmt) {
  9107. \t\t\tvar \$tbody = \$('.modal-mitsumori table tbody');
  9108. \t\t\tif (!\$tbody.length) return;
  9109. \t\t\t// 既存の動的行を全削除 (opt-row は既存実装、wt-row / wt-subsidy-row は今回追加)
  9110. \t\t\t\$tbody.find('tr.wt-row, tr.wt-subsidy-row').remove();
  9111. \t\t\tvar \$itemRow = \$tbody.find('tr').first();
  9112. \t\t\tvar fmt = new Intl.NumberFormat('ja-JP');
  9113. \t\t\tif (!window_types || window_types.length === 0) {
  9114. \t\t\t\t// 集計対象なし → 商品名行を表示に戻す
  9115. \t\t\t\t\$itemRow.show();
  9116. \t\t\t\treturn;
  9117. \t\t\t}
  9118. \t\t\twindow_types.forEach(function(wt, i) {
  9119. \t\t\t\tvar label = '窓タイプ' + (i + 1) + ':'
  9120. \t\t\t\t\t+ (wt.subtype || '') + ' / '
  9121. \t\t\t\t\t+ (wt.w || '') + '×' + (wt.h || '') + ' / '
  9122. \t\t\t\t\t+ (wt.glass || '') + ' / '
  9123. \t\t\t\t\t+ (wt.color || '');
  9124. \t\t\t\tvar \$tr = \$('<tr class=\"wt-row\"></tr>')
  9125. \t\t\t\t\t.append('<td>' + label + '</td>')
  9126. \t\t\t\t\t.append('<td>' + wt.setqty + '</td>')
  9127. \t\t\t\t\t.append('<td>セット</td>')
  9128. \t\t\t\t\t.append('<td>' + fmt.format(wt.unit_price_inc) + '円</td>')
  9129. \t\t\t\t\t.append('<td>' + fmt.format(wt.line_total_inc) + '円</td>');
  9130. \t\t\t\t\$itemRow.before(\$tr);
  9131. \t\t\t});
  9132. \t\t\t// 元の商品名行は複数タイプに置換されたので非表示
  9133. \t\t\t\$itemRow.hide();
  9134. \t\t\t// 補助金(割引額)行を末尾に追加
  9135. \t\t\tif (subsidyAmt > 0) {
  9136. \t\t\t\tvar \$subRow = \$('<tr class=\"wt-subsidy-row\"></tr>')
  9137. \t\t\t\t\t.append('<td>補助金(割引額)</td>')
  9138. \t\t\t\t\t.append('<td>1</td>')
  9139. \t\t\t\t\t.append('<td>式</td>')
  9140. \t\t\t\t\t.append('<td>-' + fmt.format(subsidyAmt) + '円</td>')
  9141. \t\t\t\t\t.append('<td>-' + fmt.format(subsidyAmt) + '円</td>');
  9142. \t\t\t\t\$tbody.append(\$subRow);
  9143. \t\t\t}
  9144. \t\t}
  9145. \t\t// 公開: onWindowTypeAxisChange (UI 骨格 task 1) からも呼ばれる
  9146. \t\twindow.recalcAll = recalcAllForSaleType2;
  9147. \t\t// 公開: ガラス選択肢が補助金対象か (窓タイプブロック生成時のバッジ判定に使う).
  9148. \t\t// subtype は P→S に落とすことはあっても null にはしないため、性能区分の
  9149. \t\t// 対象/対象外は subtype に依存しない。ここでは series/product 上限のみ適用し、
  9150. \t\t// finalizeGlassGrade が null でなければ「補助金対象ガラス」と判定する。
  9151. \t\twindow.glassYieldsSubsidy = function(glassName) {
  9152. \t\t\tif (!glassName) return false;
  9153. \t\t\treturn finalizeGlassGrade(detectGlassPerformance(glassName), '') !== null;
  9154. \t\t};
  9155. \t\tfunction mitsumori_simulation(type , value_id){
  9156. \t\t\t// sale_type=2 (補助金窓) は複数タイプ集計 UI に統合済み. 既存 mitsumori_simulation は使わない.
  9157. \t\t\tif (typeof SALE_TYPE_ID !== 'undefined' && SALE_TYPE_ID == 2) {
  9158. \t\t\t\t// type/value_id が op\\d+ (施工オプション) の場合はグローバル変数を先に更新
  9159. \t\t\t\tif (type && /^op\\d+\$/.test(type) && value_id) {
  9160. \t\t\t\t\tvar v = \$('#'+value_id).val();
  9161. \t\t\t\t\tif (type === 'op0')  op0  = v;
  9162. \t\t\t\t\tif (type === 'op1')  op1  = v;
  9163. \t\t\t\t\tif (type === 'op2')  op2  = v;
  9164. \t\t\t\t\tif (type === 'op3')  op3  = v;
  9165. \t\t\t\t\tif (type === 'op4')  op4  = v;
  9166. \t\t\t\t\tif (type === 'op5')  op5  = v;
  9167. \t\t\t\t\tif (type === 'op6')  op6  = v;
  9168. \t\t\t\t\tif (type === 'op7')  op7  = v;
  9169. \t\t\t\t\tif (type === 'op8')  op8  = v;
  9170. \t\t\t\t\tif (type === 'op9')  op9  = v;
  9171. \t\t\t\t\tif (type === 'op10') op10 = v;
  9172. \t\t\t\t}
  9173. \t\t\t\trecalcAllForSaleType2();
  9174. \t\t\t\treturn;
  9175. \t\t\t}
  9176. \t\t\t// 価格データ未登録 (pp 行 0 件) の商品は axis 入力に依存せず
  9177. \t\t\t// 「価格データ準備中」を表示して終了する.
  9178. \t\t\t// (例: scrape 未対象の新規商品 — um のウチリモ 7487/7488 等)
  9179. \t\t\tif (!pp || pp.length === 0) {
  9180. \t\t\t\t\$('#mitsumori_message').text(\"価格データ準備中\");
  9181. \t\t\t\t\$('#mitsumori_btn').hide();
  9182. \t\t\t\t\$('#mitsumori_goukei').text(\"---円\");
  9183. \t\t\t\t\$('#mitsumori_off').text(\"---円\");
  9184. \t\t\t\t\$('#mitsumori_price').text(\"---円\");
  9185. \t\t\t\t\$('#maker_price').text(\"---円\");
  9186. \t\t\t\t\$('#mitsumori_ct').text(\"---円\");
  9187. \t\t\t\t\$('#mitsumori_option').text(\"---円\");
  9188. \t\t\t\t\$('#mitsumori_kei').text(\"---円\");
  9189. \t\t\t\t\$('#mitsumori_shoukei').text(\"---円\");
  9190. \t\t\t\t\$('#mitsumori_tax').text(\"---円\");
  9191. \t\t\t\treturn;
  9192. \t\t\t}
  9193. \t\t\tif(type == \"pw\"){
  9194. \t\t\t\tpw = \$('#'+value_id).val();
  9195. \t\t\t}
  9196. \t\t\tif(type == \"pd\"){
  9197. \t\t\t\tpd = \$('#'+value_id).val();
  9198. \t\t\t}
  9199. \t\t\tif(type == \"ph\"){
  9200. \t\t\t\tph = \$('#'+value_id).val();
  9201. \t\t\t}
  9202. \t\t\tif(type == \"pm\"){
  9203. \t\t\t\tpm = \$('#'+value_id).val();
  9204. \t\t\t}
  9205. \t\t\tif(type == \"pc\"){
  9206. \t\t\t\tpc = \$('#'+value_id).val();
  9207. \t\t\t}
  9208. \t\t\tif(type == \"option1\"){
  9209. \t\t\t\toption1 = \$('#'+value_id).val();
  9210. \t\t\t}
  9211. \t\t\tif(type == \"option2\"){
  9212. \t\t\t\toption2 = \$('#'+value_id).val();
  9213. \t\t\t}
  9214. \t\t\tif(type == \"op0\"){ op0 = \$('#'+value_id).val(); }
  9215. \t\t\tif(type == \"op1\"){ op1 = \$('#'+value_id).val(); }
  9216. \t\t\tif(type == \"op2\"){ op2 = \$('#'+value_id).val(); }
  9217. \t\t\tif(type == \"op3\"){ op3 = \$('#'+value_id).val(); }
  9218. \t\t\tif(type == \"op4\"){ op4 = \$('#'+value_id).val(); }
  9219. \t\t\tif(type == \"op5\"){ op5 = \$('#'+value_id).val(); }
  9220. \t\t\tif(type == \"op6\"){ op6 = \$('#'+value_id).val(); }
  9221. \t\t\tif(type == \"op7\"){ op7 = \$('#'+value_id).val(); }
  9222. \t\t\tif(type == \"op8\"){ op8 = \$('#'+value_id).val(); }
  9223. \t\t\tif(type == \"op9\"){ op9 = \$('#'+value_id).val(); }
  9224. \t\t\tif(type == \"op10\"){ op10 = \$('#'+value_id).val(); }
  9225. \t\t\t// op0 が「商品購入のみ」のとき、他のオプション (op1..op10) を disable 化.
  9226. \t\t\t// 価格計算側 (calcGoukei の purchaseOnly 分岐) は既にゼロ化しているが、
  9227. \t\t\t// UI で選択可能に見えるとユーザーが混乱するため radio を完全に無効化する.
  9228. \t\t\t(function applyPurchaseOnlyUI() {
  9229. \t\t\t\tvar isPurchaseOnly = (op0 === '商品購入のみ');
  9230. \t\t\t\tfor (var k = 1; k <= 10; k++) {
  9231. \t\t\t\t\tvar \$inputs = \$('input[name=\"op' + k + '\"]');
  9232. \t\t\t\t\tif (\$inputs.length === 0) continue;
  9233. \t\t\t\t\t\$inputs.prop('disabled', isPurchaseOnly);
  9234. \t\t\t\t\tvar \$group = \$inputs.first().closest('.form-group');
  9235. \t\t\t\t\t\$group.css({
  9236. \t\t\t\t\t\t'opacity':        isPurchaseOnly ? '0.4'  : '1',
  9237. \t\t\t\t\t\t'pointer-events': isPurchaseOnly ? 'none' : 'auto'
  9238. \t\t\t\t\t});
  9239. \t\t\t\t}
  9240. \t\t\t})();
  9241. \t\t\t// 全 type 共通: 該当 radio を checked にし、ボタンの is-selected を付け替え + ラベル更新.
  9242. \t\t\t//   value_id が指定されていて、対応する DOM 要素が opt-btn 配下にあれば適用する.
  9243. \t\t\t//   (icheck-danger 形式から opt-btn 形式に統一した際、option1/option2/pw/pd/ph/pm/pc 等の
  9244. \t\t\t//    クリックで is-selected が更新されない不具合があったため、op\\d+ 限定の処理を一般化)
  9245. \t\t\tif (value_id) {
  9246. \t\t\t\tvar \$clicked = \$('#' + value_id);
  9247. \t\t\t\tif (\$clicked.length && \$clicked.closest('.opt-btn').length) {
  9248. \t\t\t\t\t\$clicked.prop('checked', true);
  9249. \t\t\t\t\tvar groupName = \$clicked.attr('name');
  9250. \t\t\t\t\t\$('input[name=\"' + groupName + '\"]').closest('.opt-btn').removeClass('is-selected');
  9251. \t\t\t\t\t\$clicked.closest('.opt-btn').addClass('is-selected');
  9252. \t\t\t\t\tvar \$group = \$clicked.closest('.form-group');
  9253. \t\t\t\t\tvar \$label = \$group.find('.rp-section-label');
  9254. \t\t\t\t\tif (\$label.length) {
  9255. \t\t\t\t\t\tvar labelText = \$label.text().split(':')[0].trim();
  9256. \t\t\t\t\t\t\$label.html(labelText + ': <span>' + \$clicked.val() + '</span>');
  9257. \t\t\t\t\t}
  9258. \t\t\t\t\t// op_data の price=0 & 解体/撤去/設置場所 オプションの場合、ON 選択時に「現場調査後に正式お見積もり」文言を表示.
  9259. \t\t\t\t\t//   (twig 側で is_removal_unknown ブロックを描画済み。display 切替のみ JS で行う)
  9260. \t\t\t\t\tif (/^op\\d+\$/.test(type)) {
  9261. \t\t\t\t\t\tvar opIdx = type.replace('op', '');
  9262. \t\t\t\t\t\tvar opEntry = op_data[parseInt(opIdx)];
  9263. \t\t\t\t\t\tif (opEntry) {
  9264. \t\t\t\t\t\t\tvar \$note = \$group.find('.opt-survey-note[data-op-idx=\"' + opIdx + '\"]');
  9265. \t\t\t\t\t\t\tif (\$note.length) {
  9266. \t\t\t\t\t\t\t\tvar isOn = (\$clicked.val() === opEntry.on);
  9267. \t\t\t\t\t\t\t\t\$note.toggle(isOn);
  9268. \t\t\t\t\t\t\t}
  9269. \t\t\t\t\t\t}
  9270. \t\t\t\t\t\t// wd (sale_type=5) のステップ / デッキフェンス用の注記もここで切替.
  9271. \t\t\t\t\t\t//   ステップ → deck_step (op0 だが op_data 範囲外), 必要 選択時に表示.
  9272. \t\t\t\t\t\tvar radioName = \$clicked.attr('name');
  9273. \t\t\t\t\t\tif (radioName === 'deck_step') {
  9274. \t\t\t\t\t\t\t\$group.find('.opt-survey-note-wd-step').toggle(\$clicked.val() === '必要');
  9275. \t\t\t\t\t\t} else if (radioName === 'deck_fence') {
  9276. \t\t\t\t\t\t\t\$group.find('.opt-survey-note-wd-fence').toggle(\$clicked.val() === '必要');
  9277. \t\t\t\t\t\t}
  9278. \t\t\t\t\t}
  9279. \t\t\t\t}
  9280. \t\t\t}
  9281. \t\t\t// 必須項目チェックは sale_type 1 系(カーポート/物置/フェンスなど価格マトリクス必要)に限定
  9282. \t\t\tvar requireMatrix = (SALE_TYPE_ID == 1 || SALE_TYPE_ID == 2 || SALE_TYPE_ID == 3 || SALE_TYPE_ID == 4 || SALE_TYPE_ID == 5 || SALE_TYPE_ID == 6 || SALE_TYPE_ID == 7 || SALE_TYPE_ID == 9);
  9283. \t\t\t// sale_type=3 (物置・ゴミステーション・照明 等) では「素材」を選択肢として扱わない.
  9284. \t\t\t//   - mo/gs/sy は m が \"指定なし\" など名目的にしか入っていない
  9285. \t\t\t//   - sl は m が空のままで matrix に行が来る
  9286. \t\t\t//   そのため pm の必須チェックを sale_type=3 でスキップする。
  9287. \t\t\tvar pmRequired = (SALE_TYPE_ID != 3);
  9288. \t\t\tif (requireMatrix) {
  9289. \t\t\t\tif(pmRequired && pm == \"\"){
  9290. \t\t\t\t\t\$('#mitsumori_message').text(\"素材を選択してください\");
  9291. \t\t\t\t}
  9292. \t\t\t\tif(ph == \"\"){
  9293. \t\t\t\t\t\$('#mitsumori_message').text(\"高さを選択してください\");
  9294. \t\t\t\t}
  9295. \t\t\t\tif(pd == \"\"){
  9296. \t\t\t\t\t\$('#mitsumori_message').text(\"奥行きを選択してください\");
  9297. \t\t\t\t}
  9298. \t\t\t\tif(pw == \"\"){
  9299. \t\t\t\t\t\$('#mitsumori_message').text(\"幅を選択してください\");
  9300. \t\t\t\t}
  9301. \t\t\t\tif(pc == \"\"){
  9302. \t\t\t\t\t\$('#mitsumori_message').text(\"カラーを選択してください\");
  9303. \t\t\t\t\t\$('#mitsumori_btn').hide();
  9304. \t\t\t\t\t\$('#mitsumori_goukei').text(\"---円\");
  9305. \t\t\t\t\t\$('#mitsumori_off').text(\"---円\");
  9306. \t\t\t\t\t\$('#mitsumori_price').text(\"---円\");
  9307. \t\t\t\t\t\$('#maker_price').text(\"---円\");
  9308. \t\t\t\t\t\$('#mitsumori_ct').text(\"---円\");
  9309. \t\t\t\t\t\$('#mitsumori_option').text(\"---円\");
  9310. \t\t\t\t}
  9311. \t\t\t}
  9312. \t\t\tif(pw != \"\" && pd != \"\" && ph != \"\" && (!pmRequired || pm != \"\") && pc != \"\"){
  9313. \t\t\t\t\$('#mitsumori_btn').show();
  9314. \t\t\t\t// 入力コンテキスト(sale_type 別パラメータ)
  9315. \t\t\t\tvar ctx = {
  9316. \t\t\t\t\tset_count:    parseInt(\$('#set_count').val())    || 1,
  9317. \t\t\t\t\tdaisu:        parseInt(\$('#daisu').val())        || 1,
  9318. \t\t\t\t\tmaisu:        parseInt(\$('#maisu').val())        || 3,
  9319. \t\t\t\t\tsuuryou:      parseInt(\$('#suuryou').val())      || 1,
  9320. \t\t\t\t\tarea:         (function(){
  9321. \t\t\t\t\t\t// tf(人工芝): 施工サイズ 縦(m)×横(m) から面積を算出し #area に反映.
  9322. \t\t\t\t\t\tvar L = parseFloat(\$('#tf_len').val()) || 0;
  9323. \t\t\t\t\t\tvar W = parseFloat(\$('#tf_wid').val()) || 0;
  9324. \t\t\t\t\t\tif (L > 0 && W > 0) { var a = L * W; \$('#area').val(a); return a; }
  9325. \t\t\t\t\t\treturn parseFloat(\$('#area').val()) || 0;
  9326. \t\t\t\t\t})(),
  9327. \t\t\t\t\ttf_len:       parseFloat(\$('#tf_len').val())     || 0,
  9328. \t\t\t\t\ttf_wid:       parseFloat(\$('#tf_wid').val())     || 0,
  9329. \t\t\t\t\ttf_qty:       parseInt(\$('#tf_qty').val())       || 1,
  9330. \t\t\t\t\tquantityOnly: parseInt(\$('#quantity_only').val())|| 1,
  9331. \t\t\t\t\tmado_w:       \$('#mado_w').val() || '',
  9332. \t\t\t\t\tmado_h:       \$('#mado_h').val() || '',
  9333. \t\t\t\t\tmado_type:    \$('input[name=mado_type]:checked').val()  || '',
  9334. \t\t\t\t\tglass_type:   \$('input[name=glass_type]:checked').val() || '',
  9335. \t\t\t\t\tdeck_step:    \$('input[name=deck_step]:checked').val()  || '',
  9336. \t\t\t\t\tdeck_fence:   \$('input[name=deck_fence]:checked').val() || '',
  9337. \t\t\t\t};
  9338. \t\t\t\t// 施工オプション集計(残土処理を含む)
  9339. \t\t\t\tvar opCalc = collectOptions();
  9340. \t\t\t\tvar pp_matched = false;
  9341. \t\t\t\t// 各軸の汎用 axisMatch:
  9342. \t\t\t\t//   user 選択 == matrix 値 / user \"指定なし\" / matrix 値が空
  9343. \t\t\t\tvar axisMatch = function(input, value){
  9344. \t\t\t\t    return input == value || input == \"指定なし\" || value === \"\" || value == null;
  9345. \t\t\t\t};
  9346. \t\t\t\t// 色専用マッチャー: scraper のデータ形式に合わせて拡張する
  9347. \t\t\t\t//   1. 完全一致 / \"指定なし\" / 値が空 → 真 (axisMatch と同じ)
  9348. \t\t\t\t//   2. matrix 値が \"色1/色2/色3\" の形 (同価格グループ) → split して user 選択が含まれれば真
  9349. \t\t\t\t// scraper のロジック (scraper_price.py L765-779):
  9350. \t\t\t\t//   全色同価格 → c=\"\"、価格違いグループあり → 各 group を \"/\" 結合した色名で 1 行
  9351. \t\t\t\tvar colorMatch = function(input, value){
  9352. \t\t\t\t    if (axisMatch(input, value)) return true;
  9353. \t\t\t\t    if (typeof value === 'string' && value.indexOf('/') !== -1 && input) {
  9354. \t\t\t\t        var parts = value.split('/');
  9355. \t\t\t\t        for (var idx = 0; idx < parts.length; idx++) {
  9356. \t\t\t\t            if (parts[idx].trim() === input) return true;
  9357. \t\t\t\t        }
  9358. \t\t\t\t    }
  9359. \t\t\t\t    return false;
  9360. \t\t\t\t};
  9361. \t\t\t\t// 他軸 (w/d/h/m + option1/option2) でマッチする pp 行を抽出.
  9362. \t\t\t\t// option1/option2 は um の subtype 等で使われる. axisMatch は free_area 側が
  9363. \t\t\t\t// 空のとき真を返すので、um 以外のカテゴリ (option 軸を使わない) でも影響なし.
  9364. \t\t\t\tvar candidates = pp.filter(function(el){
  9365. \t\t\t\t    return axisMatch(pw, el.w) && axisMatch(pd, el.d) && axisMatch(ph, el.h) && axisMatch(pm, el.m)
  9366. \t\t\t\t        && axisMatch(option1, el.option1) && axisMatch(option2, el.option2);
  9367. \t\t\t\t});
  9368. \t\t\t\t// フォールバック: 全軸一致が 0 件のときに限り option1/option2 を無視して再マッチ。
  9369. \t\t\t\t// 玄関ドア等で option1(なし/ランマ付き)・option2(◯◯タイプ) が pm(開き方) から
  9370. \t\t\t\t// 導出可能な冗長軸で、未選択だと全軸 AND 一致を満たせず価格が出ない事象の救済。
  9371. \t\t\t\t// pm/幅/奥行/高さ は従来どおり一致を要求するため通常商品の価格選択に影響しない。
  9372. \t\t\t\tif (candidates.length === 0) {
  9373. \t\t\t\t    candidates = pp.filter(function(el){
  9374. \t\t\t\t        return axisMatch(pw, el.w) && axisMatch(pd, el.d) && axisMatch(ph, el.h) && axisMatch(pm, el.m);
  9375. \t\t\t\t    });
  9376. \t\t\t\t}
  9377. \t\t\t\tvar picked = null;
  9378. \t\t\t\t// 優先 1: 色も含めて完全一致 (\"色1/色2\" 形式の split match を含む)
  9379. \t\t\t\tfor (var ii = 0; ii < candidates.length; ii++) {
  9380. \t\t\t\t    if (colorMatch(pc, candidates[ii].c)) { picked = candidates[ii]; break; }
  9381. \t\t\t\t}
  9382. \t\t\t\t// 優先 2: 完全一致なし & user の pc が候補のどの c 値にも該当しない (= 命名違い等)
  9383. \t\t\t\t//   かつ候補全行で price が一致する場合は、色軸を実質無視して先頭行を採用.
  9384. \t\t\t\t//   例 id=3353: pp.c は \"ステンカラー+...\" 6種だが price は全て同じなので
  9385. \t\t\t\t//     SM(スミ) を選んでも安全に最初の行の価格を返せる.
  9386. \t\t\t\tif (!picked && candidates.length > 0) {
  9387. \t\t\t\t    var ppCsInCand = candidates.map(function(r){ return r.c || ''; });
  9388. \t\t\t\t    var pcAbsent = (pc !== '' && pc !== '指定なし' && ppCsInCand.indexOf(pc) === -1
  9389. \t\t\t\t                    && ppCsInCand.every(function(v){ return v.indexOf('/') === -1 || v.split('/').map(function(s){return s.trim();}).indexOf(pc) === -1; }));
  9390. \t\t\t\t    if (pcAbsent) {
  9391. \t\t\t\t        var uniqPrices = new Set();
  9392. \t\t\t\t        candidates.forEach(function(r){ uniqPrices.add(String(r.price)); });
  9393. \t\t\t\t        if (uniqPrices.size === 1) {
  9394. \t\t\t\t            // 全候補同価格 → 色軸を wildcard 扱いで OK
  9395. \t\t\t\t            picked = candidates[0];
  9396. \t\t\t\t        }
  9397. \t\t\t\t        // 価格が異なる場合は意図的に picked=null のまま「対応しておりません」.
  9398. \t\t\t\t    }
  9399. \t\t\t\t}
  9400. \t\t\t\tpp.forEach((el) => {
  9401. \t\t\t\t  if (el === picked) {
  9402. \t\t\t\t\tpp_matched = true;
  9403. \t\t\t\t\t// tg block-keyed オプション差額を集計 (tg 以外は total=0)
  9404. \t\t\t\t\tvar oiCalc = collectOptionItems(el.w || '', el.d || '');
  9405. \t\t\t\t\t// tg ブロックに合わせてラジオを再描画 (tg 以外は no-op)
  9406. \t\t\t\t\trenderOptionItemRadios(el.w || '', el.d || '');
  9407. \t\t\t\t\t// fe ブロックの種類×段数 サブ radio (fe 以外/未設定は no-op)
  9408. \t\t\t\t\trenderFeBlockRadios();
  9409. \t\t\t\t\t// fe ご希望のフェンス設置方法 — 「既存ブロックに穴空け」 entry の連動表示
  9410. \t\t\t\t\tupdateFeOpConditionalVisibility();
  9411. \t\t\t\t\tvar calc       = calcGoukei(el, opCalc.total, ctx);
  9412. \t\t\t\t\tvar goukei     = calc.goukei;
  9413. \t\t\t\t\tvar price      = calc.price;
  9414. \t\t\t\t\tvar ct         = calc.ct;
  9415. \t\t\t\t\tvar optionSum  = calc.opt;
  9416. \t\t\t\t\t// tf(人工芝): 必要枚数入力へ算出結果を反映(施工サイズ入力時は上書き、
  9417. \t\t\t\t\t// 直接指定時は同値なので実質変化なし。要素が無い sale_type では no-op)
  9418. \t\t\t\t\tvar \$tfQty = \$('#tf_qty');
  9419. \t\t\t\t\tif (\$tfQty.length) \$tfQty.val(calc.qty || 1);
  9420. \t\t\t\t\t// オプション差額は税抜 → 税込に変換して合計に加算
  9421. \t\t\t\t\tvar oiIncTax   = toIncTax(oiCalc.total);
  9422. \t\t\t\t\tgoukei += oiIncTax;
  9423. \t\t\t\t\tprice  += oiIncTax;  // 差額は本体価格扱いとして mitsumori_price にも加算
  9424. \t\t\t\t\t// maker_price も scraper が税抜で保存しているため税込に変換
  9425. \t\t\t\tvar makerPrice = toIncTax(parseInt(el.maker_price) || 0);
  9426. \t\t\t\t\t\$('#mitsumori_message').text(formatter.format(goukei) + \"円\");
  9427. \t\t\t\t\t\$('#mitsumori_goukei').text(formatter.format(goukei) + \"円\");
  9428. \t\t\t\t\t\$('#mitsumori_off').text(formatter.format(price - makerPrice) + \"円\");
  9429. \t\t\t\t\t\$('#mitsumori_price').text(formatter.format(price) + \"円\");
  9430. \t\t\t\t\t\$('#maker_price').text(formatter.format(makerPrice) + \"円\");
  9431. \t\t\t\t\t\$('#mitsumori_ct').text(formatter.format(ct) + \"円\");
  9432. \t\t\t\t\t\$('#mitsumori_option').text(formatter.format(optionSum) + \"円\");
  9433. \t\t\t\t\t\$('#mitsumori_kei').text(formatter.format(goukei) + \"円\");
  9434. \t\t\t\t\t\$('#mitsumori_price_01').text(formatter.format(price) + \"円\");
  9435. \t\t\t\t\t\$('#mitsumori_price_02').text(formatter.format(price) + \"円\");
  9436. \t\t\t\t\t\$('#mitsumori_ct_01').text(formatter.format(ct) + \"円\");
  9437. \t\t\t\t\t\$('#mitsumori_ct_02').text(formatter.format(ct) + \"円\");
  9438. \t\t\t\t\t\$('#mitsumori_goukei_02').text(formatter.format(goukei) + \"円\");
  9439. \t\t\t\t\tvar shoukei = goukei / 1.1;
  9440. \t\t\t\t\tvar tax     = parseInt(goukei - shoukei);
  9441. \t\t\t\t\t\$('#mitsumori_shoukei').text(formatter.format(parseInt(shoukei)) + \"円\");
  9442. \t\t\t\t\t\$('#mitsumori_tax').text(formatter.format(tax) + \"円\");
  9443. \t\t\t\t\t// PDF 明細用:オプション内訳テーブルを差し込む (施工オプション + tg block オプション)
  9444. \t\t\t\t\trenderOptionDetailRows(opCalc.items.concat(oiCalc.items.map(function(it){
  9445. \t\t\t\t\t\treturn { name: it.name, value: it.label, price: it.diff };
  9446. \t\t\t\t\t})));
  9447. \t\t\t\t  }
  9448. \t\t\t\t});
  9449. \t\t\t\tif (!pp_matched) {
  9450. \t\t\t\t\t\$('#mitsumori_message').text(\"この組み合わせは対応しておりません\");
  9451. \t\t\t\t\t\$('#mitsumori_btn').hide();
  9452. \t\t\t\t\t\$('#mitsumori_goukei').text(\"---円\");
  9453. \t\t\t\t\t\$('#mitsumori_off').text(\"---円\");
  9454. \t\t\t\t\t\$('#mitsumori_price').text(\"---円\");
  9455. \t\t\t\t\t\$('#maker_price').text(\"---円\");
  9456. \t\t\t\t\t\$('#mitsumori_ct').text(\"---円\");
  9457. \t\t\t\t\t\$('#mitsumori_option').text(\"---円\");
  9458. \t\t\t\t\t\$('#mitsumori_kei').text(\"---円\");
  9459. \t\t\t\t\t\$('#mitsumori_shoukei').text(\"---円\");
  9460. \t\t\t\t\t\$('#mitsumori_tax').text(\"---円\");
  9461. \t\t\t\t}
  9462. \t\t\t\t// mitsumori_json: バック側に送信する見積データ
  9463. \t\t\t\tvar mitsumori_json = { \"mitsumori_goukei\": \$('#mitsumori_goukei').text(),
  9464. \t\t\t\t\t\t\t\t\t\t\"mitsumori_goukei_02\": \$('#mitsumori_goukei_02').text(),
  9465. \t\t\t\t\t\t\t\t\t\t\"mitsumori_price\": \$('#mitsumori_price').text(),
  9466. \t\t\t\t\t\t\t\t\t\t\"maker_price\": \$('#maker_price').text(),
  9467. \t\t\t\t\t\t\t\t\t\t\"mitsumori_off\": \$('#mitsumori_off').text(),
  9468. \t\t\t\t\t\t\t\t\t\t\"mitsumori_ct\": \$('#mitsumori_ct').text(),
  9469. \t\t\t\t\t\t\t\t\t\t\"mitsumori_option\": \$('#mitsumori_option').text(),
  9470. \t\t\t\t\t\t\t\t\t\t\"product_id\": {{ Product.id }},
  9471. \t\t\t\t\t\t\t\t\t\t\"sale_type\": SALE_TYPE_ID,
  9472. \t\t\t\t\t\t\t\t\t\t\"pw\": pw,
  9473. \t\t\t\t\t\t\t\t\t\t\"pd\": pd,
  9474. \t\t\t\t\t\t\t\t\t\t\"ph\": ph,
  9475. \t\t\t\t\t\t\t\t\t\t\"pm\": pm,
  9476. \t\t\t\t\t\t\t\t\t\t\"pc\": pc,
  9477. \t\t\t\t\t\t\t\t\t\t\"op\": [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10],
  9478. \t\t\t\t\t\t\t\t\t\t\"op_items\": opCalc.items,
  9479. \t\t\t\t\t\t\t\t\t\t\"mado_w\":     ctx.mado_w,
  9480. \t\t\t\t\t\t\t\t\t\t\"mado_h\":     ctx.mado_h,
  9481. \t\t\t\t\t\t\t\t\t\t\"mado_type\":  ctx.mado_type,
  9482. \t\t\t\t\t\t\t\t\t\t\"glass_type\": ctx.glass_type,
  9483. \t\t\t\t\t\t\t\t\t\t\"set_count\":  ctx.set_count,
  9484. \t\t\t\t\t\t\t\t\t\t\"daisu\":      ctx.daisu,
  9485. \t\t\t\t\t\t\t\t\t\t\"maisu\":      ctx.maisu,
  9486. \t\t\t\t\t\t\t\t\t\t\"suuryou\":    ctx.suuryou,
  9487. \t\t\t\t\t\t\t\t\t\t\"area\":       ctx.area,
  9488. \t\t\t\t\t\t\t\t\t\t\"tf_len\":     ctx.tf_len,
  9489. \t\t\t\t\t\t\t\t\t\t\"tf_wid\":     ctx.tf_wid,
  9490. \t\t\t\t\t\t\t\t\t\t\"tf_qty\":     \$('#tf_qty').val(),
  9491. \t\t\t\t\t\t\t\t\t\t\"deck_step\":  ctx.deck_step,
  9492. \t\t\t\t\t\t\t\t\t\t\"deck_fence\": ctx.deck_fence };
  9493. \t\t\t\t\$('#mitsumori_json').val(JSON.stringify(mitsumori_json));
  9494. \t\t\t}
  9495. \t\t}
  9496. \t\t// PDF/モーダル明細の動的差し替え(基本工事費の次にオプション行を追加)
  9497. \t\tfunction renderOptionDetailRows(items) {
  9498. \t\t\tvar \$tbody = \$('.modal-mitsumori table tbody');
  9499. \t\t\tif (!\$tbody.length) return;
  9500. \t\t\t\$tbody.find('tr.opt-row').remove();
  9501. \t\t\tvar anchorRow = \$tbody.find('tr').filter(function(){
  9502. \t\t\t\treturn \$(this).find('td:first').text().indexOf('残土') !== -1
  9503. \t\t\t\t\t|| \$(this).find('td:first').text().indexOf('基本工事費') !== -1;
  9504. \t\t\t}).last();
  9505. \t\t\titems.forEach(function(it){
  9506. \t\t\t\tif (!it.name || !it.value) return;
  9507. \t\t\t\tvar priceTxt = it.price > 0
  9508. \t\t\t\t\t? formatter.format(it.price) + '円'
  9509. \t\t\t\t\t: '0円';
  9510. \t\t\t\tvar \$tr = \$('<tr class=\"opt-row\"></tr>')
  9511. \t\t\t\t\t.append('<td>' + it.name + ':' + it.value + '</td>')
  9512. \t\t\t\t\t.append('<td>1</td>')
  9513. \t\t\t\t\t.append('<td>式</td>')
  9514. \t\t\t\t\t.append('<td>' + priceTxt + '</td>')
  9515. \t\t\t\t\t.append('<td>' + (it.price > 0 ? formatter.format(it.price) + '円' : '') + '</td>');
  9516. \t\t\t\tif (anchorRow.length) {
  9517. \t\t\t\t\tanchorRow.after(\$tr);
  9518. \t\t\t\t\tanchorRow = \$tr;
  9519. \t\t\t\t} else {
  9520. \t\t\t\t\t\$tbody.append(\$tr);
  9521. \t\t\t\t}
  9522. \t\t\t});
  9523. \t\t}
  9524. \t\t// 見積書モーダルを開く直前に、右側「現在のお見積り額」パネルの表示値を
  9525. \t\t// モーダル内の対応 ID にコピーして金額の食い違いを防ぐ。
  9526. \t\t// pw/pd/ph/pm が未選択で mitsumori_simulation の full update に到達しない場合でも、
  9527. \t\t// パネル側の値(HTML 静的初期値 or 直近の simulation 結果)が modal にも反映される。
  9528. \t\tfunction syncMitsumoriModalFromPanel() {
  9529. \t\t\tvar goukeiText = \$('#mitsumori_goukei').text();
  9530. \t\t\tvar priceText  = \$('#mitsumori_price').text();
  9531. \t\t\tvar ctText     = \$('#mitsumori_ct').text();
  9532. \t\t\t\$('#mitsumori_kei').text(goukeiText);
  9533. \t\t\t\$('#mitsumori_price_01').text(priceText);
  9534. \t\t\t\$('#mitsumori_price_02').text(priceText);
  9535. \t\t\t\$('#mitsumori_ct_01').text(ctText);
  9536. \t\t\t\$('#mitsumori_ct_02').text(ctText);
  9537. \t\t\t\$('#mitsumori_goukei_02').text(goukeiText);
  9538. \t\t\t// 小計 / 消費税 は税込 goukei から逆算
  9539. \t\t\tvar num = parseInt(goukeiText.replace(/[^\\d-]/g, ''), 10);
  9540. \t\t\tif (!isNaN(num) && num > 0) {
  9541. \t\t\t\tvar shoukei = Math.round(num / 1.1);
  9542. \t\t\t\tvar tax     = num - shoukei;
  9543. \t\t\t\t\$('#mitsumori_shoukei').text(formatter.format(shoukei) + '円');
  9544. \t\t\t\t\$('#mitsumori_tax').text(formatter.format(tax) + '円');
  9545. \t\t\t} else {
  9546. \t\t\t\t\$('#mitsumori_shoukei').text('---円');
  9547. \t\t\t\t\$('#mitsumori_tax').text('---円');
  9548. \t\t\t}
  9549. \t\t}
  9550. \t\t\$(document).on('show.bs.modal', '#modal-mitsumori', function () {
  9551. \t\t\tsyncMitsumoriModalFromPanel();
  9552. \t\t});
  9553.         {# pc の auto-init: pw/pd/ph/pm と同じく p_c(matrix 派生)の length==1 or 全空で「指定なし」化.
  9554.            search_word(color) が空の「複合色」型商品で pc が空のまま放置されて
  9555.            「カラーを選択してください」固定になるバグの修正.
  9556.            search_word に登録された name があれば優先採用. #}
  9557.         {% if p_c and (p_c|length == 1 or p_c|join == \"\") %}
  9558.             pc = \"指定なし\";
  9559.             {% for pc_val in p_c %}{% if pc_val %} pc = \"{{ pc_val }}\"; {% endif %}{% endfor %}
  9560.             {% if color and color|length == 1 %}
  9561.                 {% for cc in color %}{% if cc and cc['name'] %} pc = \"{{ cc['name'] }}\"; {% endif %}{% endfor %}
  9562.             {% endif %}
  9563.         {% elseif color and color|length == 1 %}
  9564.             pc = \"指定なし\";
  9565. \t\t\t{% for cc in color %}{% if cc and cc['name'] %} pc = \"{{ cc['name'] }}\"; {% endif %}{% endfor %}
  9566. \t\t{% endif %}
  9567.         {% if p_w and (p_w|length == 1 or p_w|join == \"\") %}
  9568.             pw = \"指定なし\";
  9569. \t\t\t{% for pw in p_w %}{% if pw %} pw = \"{{ pw }}\"; {% endif %}{% endfor %}
  9570. \t\t{% endif %}
  9571.         {% if p_d and (p_d|length == 1 or p_d|join == \"\") %}
  9572.             pd = \"指定なし\";
  9573. \t\t\t{% for pd in p_d %}{% if pd %} pd = \"{{ pd }}\"; {% endif %}{% endfor %}
  9574. \t\t{% endif %}
  9575.         {% if p_h and (p_h|length == 1 or p_h|join == \"\") %}
  9576.             ph = \"指定なし\";
  9577. \t\t\t{% for ph in p_h %}{% if ph %} ph = \"{{ ph }}\"; {% endif %}{% endfor %}
  9578. \t\t{% endif %}
  9579.         {% if p_m and (p_m|length == 1 or p_m|join == \"\") %}
  9580.             pm = \"指定なし\";
  9581. \t\t\t{% for pm in p_m %}{% if pm %} pm = \"{{ pm }}\"; {% endif %}{% endfor %}
  9582. \t\t{% endif %}
  9583.         {# p_option1 / p_option2 の auto-init: length==1 or 全空で JS 変数を埋める #}
  9584.         {% if p_option1 and (p_option1|length == 1 or p_option1|join == \"\") %}
  9585.             option1 = \"\";
  9586. \t\t\t{% for opt1 in p_option1 %}{% if opt1 %} option1 = \"{{ opt1|e('js') }}\"; {% endif %}{% endfor %}
  9587. \t\t{% endif %}
  9588.         {% if p_option2 and (p_option2|length == 1 or p_option2|join == \"\") %}
  9589.             option2 = \"\";
  9590. \t\t\t{% for opt2 in p_option2 %}{% if opt2 %} option2 = \"{{ opt2|e('js') }}\"; {% endif %}{% endfor %}
  9591. \t\t{% endif %}
  9592. \t\t// カラー radio が複数あるとき初期チェックが無いと「カラーを選択してください」固定になるので、
  9593. \t\t// 何もチェックされていなければ「最初の radio」を選択する。
  9594. \t\t// sale_type≠3 は name=\"color\", sale_type=3 は name=\"color3\".
  9595. \t\t//
  9596. \t\t// 注意:
  9597. \t\t//   ・search_word(= radio の値)と pp.c(= matrix の色軸)は別の命名体系のケースがある
  9598. \t\t//     (例 id=3353: radio=\"SM(スミ)\" / pp.c=\"ステンカラー+セピアブラウン\")
  9599. \t\t//   ・pp.c に合わせて radio を選ぼうとしても文字列一致しないので無意味。
  9600. \t\t//   ・単純に「先頭の radio」を選ぶ実装に戻し、マッチング側で命名体系違いを吸収する
  9601. \t\t//     (pc が pp.c のどの値にもマッチしないときは色軸を wildcard 扱いにする)。
  9602. \t\t//   ・.rp-section-label のテキストも忘れずに同期する(古い session 値が残ると
  9603. \t\t//     \"ステンカラー+セピアブラウン\" のような表示と実際の radio が食い違う)。
  9604. \t\t(function autoSelectFirstColor(){
  9605. \t\t\tvar groups = ['color', 'color3'];
  9606. \t\t\tfor (var gi = 0; gi < groups.length; gi++) {
  9607. \t\t\t\tvar name = groups[gi];
  9608. \t\t\t\tvar nodes = document.querySelectorAll('input[type=\"radio\"][name=\"' + name + '\"]');
  9609. \t\t\t\tif (nodes.length === 0) continue;
  9610. \t\t\t\tvar anyChecked = false;
  9611. \t\t\t\tfor (var i = 0; i < nodes.length; i++) {
  9612. \t\t\t\t\tif (nodes[i].checked) { anyChecked = true; break; }
  9613. \t\t\t\t}
  9614. \t\t\t\tif (anyChecked) continue;
  9615. \t\t\t\tvar target = nodes[0];
  9616. \t\t\t\ttarget.checked = true;
  9617. \t\t\t\tpc = target.value;
  9618. \t\t\t\t// opt-btn の is-selected を付け替え
  9619. \t\t\t\tvar lbl = target.closest('.opt-btn');
  9620. \t\t\t\tif (lbl) {
  9621. \t\t\t\t\tvar sib = lbl.parentNode ? lbl.parentNode.querySelectorAll('.opt-btn') : [];
  9622. \t\t\t\t\tfor (var k = 0; k < sib.length; k++) sib[k].classList.remove('is-selected');
  9623. \t\t\t\t\tlbl.classList.add('is-selected');
  9624. \t\t\t\t}
  9625. \t\t\t\t// 「カラー: <name>」表示の同期(古い mitsumori_json.pc が残らないように)
  9626. \t\t\t\tvar grp = (lbl && lbl.closest('.form-group')) || (target.closest('.form-group'));
  9627. \t\t\t\tif (grp) {
  9628. \t\t\t\t\tvar section = grp.querySelector('.rp-section-label');
  9629. \t\t\t\t\tif (section) {
  9630. \t\t\t\t\t\tvar labelHead = section.textContent.split(':')[0].trim();
  9631. \t\t\t\t\t\tsection.innerHTML = labelHead + ': <span>' + target.value + '</span>';
  9632. \t\t\t\t\t}
  9633. \t\t\t\t}
  9634. \t\t\t}
  9635. \t\t})();
  9636. \t\t// option1 / option2 / pw / pd / ph / pm (matrix 軸の radio 群) も同様に
  9637. \t\t// 「どれもチェックされていなければ先頭を選ぶ」を適用する.
  9638. \t\t//   sale_type=2 の窓タイプ等で「初期表示時に一番初めの選択肢が選択されていない」事象を解消.
  9639. \t\t(function autoSelectFirstMatrixAxis(){
  9640. \t\t\tvar axes = [
  9641. \t\t\t\t{ name: 'pw',      jsVar: 'pw' },
  9642. \t\t\t\t{ name: 'pd',      jsVar: 'pd' },
  9643. \t\t\t\t{ name: 'ph',      jsVar: 'ph' },
  9644. \t\t\t\t{ name: 'pm',      jsVar: 'pm' },
  9645. \t\t\t\t{ name: 'glass_type', jsVar: 'pm' },
  9646. \t\t\t\t{ name: 'option1', jsVar: 'option1' },
  9647. \t\t\t\t{ name: 'option2', jsVar: 'option2' }
  9648. \t\t\t];
  9649. \t\t\tfor (var ai = 0; ai < axes.length; ai++) {
  9650. \t\t\t\tvar ax = axes[ai];
  9651. \t\t\t\tvar nodes = document.querySelectorAll('input[type=\"radio\"][name=\"' + ax.name + '\"]');
  9652. \t\t\t\tif (nodes.length === 0) continue;
  9653. \t\t\t\tvar anyChecked = false;
  9654. \t\t\t\tfor (var i = 0; i < nodes.length; i++) {
  9655. \t\t\t\t\tif (nodes[i].checked) { anyChecked = true; break; }
  9656. \t\t\t\t}
  9657. \t\t\t\tif (anyChecked) continue;
  9658. \t\t\t\tvar target = nodes[0];
  9659. \t\t\t\ttarget.checked = true;
  9660. \t\t\t\t// グローバル JS 変数も埋める
  9661. \t\t\t\tif (ax.jsVar === 'pw') pw = target.value;
  9662. \t\t\t\telse if (ax.jsVar === 'pd') pd = target.value;
  9663. \t\t\t\telse if (ax.jsVar === 'ph') ph = target.value;
  9664. \t\t\t\telse if (ax.jsVar === 'pm') pm = target.value;
  9665. \t\t\t\telse if (ax.jsVar === 'option1') option1 = target.value;
  9666. \t\t\t\telse if (ax.jsVar === 'option2') option2 = target.value;
  9667. \t\t\t\tvar lbl = target.closest('.opt-btn');
  9668. \t\t\t\tif (lbl) {
  9669. \t\t\t\t\tvar sib = lbl.parentNode ? lbl.parentNode.querySelectorAll('.opt-btn') : [];
  9670. \t\t\t\t\tfor (var k = 0; k < sib.length; k++) sib[k].classList.remove('is-selected');
  9671. \t\t\t\t\tlbl.classList.add('is-selected');
  9672. \t\t\t\t}
  9673. \t\t\t\tvar grp = (lbl && lbl.closest('.form-group')) || (target.closest('.form-group'));
  9674. \t\t\t\tif (grp) {
  9675. \t\t\t\t\tvar section = grp.querySelector('.rp-section-label');
  9676. \t\t\t\t\tif (section) {
  9677. \t\t\t\t\t\tvar labelHead = section.textContent.split(':')[0].trim();
  9678. \t\t\t\t\t\tsection.innerHTML = labelHead + ': <span>' + target.value + '</span>';
  9679. \t\t\t\t\t}
  9680. \t\t\t\t}
  9681. \t\t\t}
  9682. \t\t})();
  9683. \t\t// 取付/設置工事トグル(off 値が「商品購入のみ」のオプション)は、新規アクセス時に
  9684. \t\t// どちらの radio も未チェックのため初期価格が「商品購入のみ」= 基本工事費抜きになる。
  9685. \t\t// 顧客要望(#10)に合わせ、未選択時は「工事も希望する」(on 側) を初期選択し、
  9686. \t\t// 初期表示を基本工事費込みの最安値に統一する(色・寸法軸の先頭自動選択と同型)。
  9687. \t\t//   ・判定キーは calcGoukei / applyPurchaseOnlyUI と同じ定数「商品購入のみ」。
  9688. \t\t//   ・別用途で op{n} を流用する商品(ウッドデッキ deck_step 等)は radio 値に
  9689. \t\t//     「商品購入のみ」を含まないため対象外(既存挙動を壊さない)。
  9690. \t\t//   ・mitsumori_json 復元やユーザー操作で既に選択済みなら尊重する。
  9691. \t\t(function autoSelectFirstInstall(){
  9692. \t\t\tfor (var i = 0; i <= 10; i++) {
  9693. \t\t\t\tvar nodes = document.querySelectorAll('input[type=\"radio\"][name=\"op' + i + '\"]');
  9694. \t\t\t\tif (nodes.length === 0) continue;
  9695. \t\t\t\t// このグループが「商品購入のみ」を off に持つ工事トグルか判定し、
  9696. \t\t\t\t// 「商品購入のみ」でない側 (= 工事希望 on) を取得する。
  9697. \t\t\t\tvar hasPurchaseOnly = false;
  9698. \t\t\t\tvar onNode = null;
  9699. \t\t\t\tfor (var j = 0; j < nodes.length; j++) {
  9700. \t\t\t\t\tif (nodes[j].value === '商品購入のみ') hasPurchaseOnly = true;
  9701. \t\t\t\t\telse if (!onNode) onNode = nodes[j];
  9702. \t\t\t\t}
  9703. \t\t\t\tif (!hasPurchaseOnly || !onNode) continue;
  9704. \t\t\t\tvar anyChecked = false;
  9705. \t\t\t\tfor (var k = 0; k < nodes.length; k++) {
  9706. \t\t\t\t\tif (nodes[k].checked) { anyChecked = true; break; }
  9707. \t\t\t\t}
  9708. \t\t\t\tif (anyChecked) continue;
  9709. \t\t\t\tonNode.checked = true;
  9710. \t\t\t\t// グローバル op 変数を on 値で埋める(calcGoukei の purchaseOnly 判定が参照)
  9711. \t\t\t\tswitch (i) {
  9712. \t\t\t\t\tcase 0:  op0  = onNode.value; break;
  9713. \t\t\t\t\tcase 1:  op1  = onNode.value; break;
  9714. \t\t\t\t\tcase 2:  op2  = onNode.value; break;
  9715. \t\t\t\t\tcase 3:  op3  = onNode.value; break;
  9716. \t\t\t\t\tcase 4:  op4  = onNode.value; break;
  9717. \t\t\t\t\tcase 5:  op5  = onNode.value; break;
  9718. \t\t\t\t\tcase 6:  op6  = onNode.value; break;
  9719. \t\t\t\t\tcase 7:  op7  = onNode.value; break;
  9720. \t\t\t\t\tcase 8:  op8  = onNode.value; break;
  9721. \t\t\t\t\tcase 9:  op9  = onNode.value; break;
  9722. \t\t\t\t\tcase 10: op10 = onNode.value; break;
  9723. \t\t\t\t}
  9724. \t\t\t\t// opt-btn の is-selected を付け替え
  9725. \t\t\t\tvar lbl = onNode.closest('.opt-btn');
  9726. \t\t\t\tif (lbl) {
  9727. \t\t\t\t\tvar sib = lbl.parentNode ? lbl.parentNode.querySelectorAll('.opt-btn') : [];
  9728. \t\t\t\t\tfor (var s = 0; s < sib.length; s++) sib[s].classList.remove('is-selected');
  9729. \t\t\t\t\tlbl.classList.add('is-selected');
  9730. \t\t\t\t}
  9731. \t\t\t\t// rp-section-label 表示同期 + 現地調査文言(is_removal_unknown / is_tf_kouji)を on 表示に
  9732. \t\t\t\tvar grp = (lbl && lbl.closest('.form-group')) || onNode.closest('.form-group');
  9733. \t\t\t\tif (grp) {
  9734. \t\t\t\t\tvar section = grp.querySelector('.rp-section-label');
  9735. \t\t\t\t\tif (section) {
  9736. \t\t\t\t\t\tvar labelHead = section.textContent.split(':')[0].trim();
  9737. \t\t\t\t\t\tsection.innerHTML = labelHead + ': <span>' + onNode.value + '</span>';
  9738. \t\t\t\t\t}
  9739. \t\t\t\t\tvar note = grp.querySelector('.opt-survey-note[data-op-idx=\"' + i + '\"]');
  9740. \t\t\t\t\tif (note) note.style.display = '';
  9741. \t\t\t\t}
  9742. \t\t\t}
  9743. \t\t})();
  9744. \t\t// ページ読み込み時: 見積金額が「合計」になっているため、カート数量は基本1
  9745. \t\t// sale_type=9(商品のみ購入)だけ通常 EC として数量を引き継ぐ
  9746. \t\t(function initQuantityByType(){
  9747. \t\t\tvar saleType = {{ ProductClass.SaleType.id }};
  9748. \t\t\tif (saleType == 9 && \$('#quantity_only').length) {
  9749. \t\t\t\t\$('#quantity').val(parseInt(\$('#quantity_only').val()) || 1);
  9750. \t\t\t} else {
  9751. \t\t\t\t\$('#quantity').val(1);
  9752. \t\t\t\t\$('input[name=\"quantity\"]').val(1);
  9753. \t\t\t}
  9754. \t\t})();
  9755. \t\t// type → ラベルのプレフィックス文字列
  9756. \t\t// option1/option2 のラベルは category 依存 (rd: ランマ/タイプ, sh: サイズプリセット/駆動方式 等).
  9757. \t\t// PHP から渡された option1_label / option2_label を埋め込み、JS 側でラベル更新に使う.
  9758. \t\tvar optLabelMap = {pc:'カラー', pw:'幅', pd:'奥行き', ph:'高さ', pm:'素材',
  9759. \t\t                   option1: '{{ option1_label|default('オプション1')|e('js') }}',
  9760. \t\t                   option2: '{{ option2_label|default('オプション2')|e('js') }}'};
  9761. \t\t// type → input[name]
  9762. \t\tvar optNameMap  = {pc:'color', pw:'pw', pd:'pd', ph:'ph', pm:'pm',
  9763. \t\t                   option1: 'option1', option2: 'option2'};
  9764. \t\t// opt-btn用: 値を直接受け取るラッパー
  9765. \t\tfunction mitsumori_simulation_val(type, value) {
  9766. \t\t\tif (type === 'pc') pc = value;
  9767. \t\t\tif (type === 'pw') pw = value;
  9768. \t\t\tif (type === 'pd') pd = value;
  9769. \t\t\tif (type === 'ph') ph = value;
  9770. \t\t\tif (type === 'pm') pm = value;
  9771. \t\t\tif (type === 'option1') option1 = value;
  9772. \t\t\tif (type === 'option2') option2 = value;
  9773. \t\t\t// is-selected クラスを同グループ内で付け替え
  9774. \t\t\tvar inputName = optNameMap[type];
  9775. \t\t\tif (inputName) {
  9776. \t\t\t\tvar \$btns = \$('input[name=\"' + inputName + '\"]').closest('.opt-btn');
  9777. \t\t\t\t\$btns.removeClass('is-selected');
  9778. \t\t\t\t\$btns.filter(function(){
  9779. \t\t\t\t\treturn \$(this).find('input').val() === value;
  9780. \t\t\t\t}).addClass('is-selected');
  9781. \t\t\t}
  9782. \t\t\t// ラベル行の選択値テキストを更新(例: 「カラー: ブラック」)
  9783. \t\t\tvar labelPrefix = optLabelMap[type];
  9784. \t\t\tif (labelPrefix) {
  9785. \t\t\t\t// 対象のrp-section-labelを特定(input[name]を含む親を遡る)
  9786. \t\t\t\tvar \$group = \$('input[name=\"' + inputName + '\"]').first().closest('.form-group');
  9787. \t\t\t\tvar \$label = \$group.find('.rp-section-label');
  9788. \t\t\t\t\$label.html(labelPrefix + ': <span>' + value + '</span>');
  9789. \t\t\t}
  9790. \t\t\t// simulation本体を呼ぶ(value_idは空でOK、グローバル変数を使う)
  9791. \t\t\tmitsumori_simulation('', '');
  9792. \t\t}
  9793. \t\tmitsumori_simulation(\"\",\"\");
  9794. \t\t// ボタン群: 親幅を超える、または3行以上になる場合は is-scroll を付与し
  9795. \t\t// 縦3段グリッド+横スクロール表示にする(顧客要望「3列くらいで横スクロール」)
  9796. \t\tfunction applyBtnGroupScroll() {
  9797. \t\t\t\$('.rp-btn-group, .opt-btn-group').each(function() {
  9798. \t\t\t\tvar \$group = \$(this);
  9799. \t\t\t\t\$group.removeClass('is-scroll');
  9800. \t\t\t\tvar \$items = \$group.children();
  9801. \t\t\t\tif (\$items.length === 0) return;
  9802. \t\t\t\tvar parentWidth = \$group.parent().width() || \$group.width();
  9803. \t\t\t\tvar totalWidth = 0;
  9804. \t\t\t\tvar gap = parseInt(\$group.css('gap'), 10) || 8;
  9805. \t\t\t\t\$items.each(function() {
  9806. \t\t\t\t\ttotalWidth += this.offsetWidth + gap;
  9807. \t\t\t\t});
  9808. \t\t\t\t// 単一ボタンが親幅を超える、もしくは合計幅が親幅を超える → 横スクロール化
  9809. \t\t\t\tvar anyTooWide = false;
  9810. \t\t\t\t\$items.each(function() {
  9811. \t\t\t\t\tif (this.offsetWidth > parentWidth) { anyTooWide = true; return false; }
  9812. \t\t\t\t});
  9813. \t\t\t\t// 折り返し時の行数も計測
  9814. \t\t\t\tvar tops = {};
  9815. \t\t\t\t\$items.each(function() { tops[this.offsetTop] = true; });
  9816. \t\t\t\tvar rowCount = Object.keys(tops).length;
  9817. \t\t\t\tif (anyTooWide || totalWidth > parentWidth * 2 || rowCount >= 3) {
  9818. \t\t\t\t\t\$group.addClass('is-scroll');
  9819. \t\t\t\t}
  9820. \t\t\t});
  9821. \t\t}
  9822. \t\tapplyBtnGroupScroll();
  9823. \t\t\$(window).on('resize', function() {
  9824. \t\t\tclearTimeout(window._btnScrollTimer);
  9825. \t\t\twindow._btnScrollTimer = setTimeout(applyBtnGroupScroll, 150);
  9826. \t\t});
  9827. \t\t// onload: 見積金額が確定している場合は「工事費込み価格」表示を一致させる
  9828. \t\t(function syncPrice02Display() {
  9829. \t\t\tvar goukeiEl = document.getElementById('mitsumori_goukei');
  9830. \t\t\tvar displayEl = document.getElementById('price02-display');
  9831. \t\t\tif (!goukeiEl || !displayEl) return;
  9832. \t\t\tvar goukeiText = goukeiEl.textContent.trim();
  9833. \t\t\t// ---円(未確定)の場合は書き換えない
  9834. \t\t\tif (goukeiText && goukeiText !== '---円') {
  9835. \t\t\t\tdisplayEl.textContent = goukeiText;
  9836. \t\t\t}
  9837. \t\t\t// 以降の変更にも追従: mitsumori_goukei を監視
  9838. \t\t\tnew MutationObserver(function() {
  9839. \t\t\t\tvar text = goukeiEl.textContent.trim();
  9840. \t\t\t\tif (text && text !== '---円') {
  9841. \t\t\t\t\tdisplayEl.textContent = text;
  9842. \t\t\t\t}
  9843. \t\t\t}).observe(goukeiEl, { childList: true, subtree: true, characterData: true });
  9844. \t\t})();
  9845. \t\tfunction contact_form(product_id){
  9846. \t\t\t\$('#form1').attr('action', '{{ url('contact', {product:Product.id}) }}');
  9847. \t\t\t\$('#form1').submit();
  9848. \t\t}
  9849. \t\t// maisu / madoset は下部の新しい関数定義を使用
  9850. \t\tfunction heibei(bei){
  9851. \t\t\t\$('#heibei').val(parseInt(\$('#heibei').val()) + bei);
  9852. \t\t\tif(parseInt(\$('#heibei').val()) < 1){ \$('#heibei').val(1); }
  9853. \t\t\tif(parseInt(\$('#heibei').val()) > 100){ \$('#heibei').val(100); }
  9854. \t\t\t// goukei に既に枚数を含むため、カート数量は1で固定
  9855. \t\t\t\$('#quantity').val(1);
  9856. \t\t\tmitsumori_simulation('heibei','heibei');
  9857. \t\t}
  9858. \t\tfunction daisu(dai){
  9859. \t\t\t\$('#daisu').val(parseInt(\$('#daisu').val()) + dai);
  9860. \t\t\tif(parseInt(\$('#daisu').val()) < 1){ \$('#daisu').val(1); }
  9861. \t\t\tif(parseInt(\$('#daisu').val()) > 10){ \$('#daisu').val(10); }
  9862. \t\t\t\$('#quantity').val(1);
  9863. \t\t\tmitsumori_simulation('daisu','daisu');
  9864. \t\t}
  9865. \t\t// sale_type=7(数量買い・基本工事費固定)用:個数入力
  9866. \t\tfunction suuryou(n){
  9867. \t\t\t\$('#suuryou').val(parseInt(\$('#suuryou').val()) + n);
  9868. \t\t\tif(parseInt(\$('#suuryou').val()) < 1){ \$('#suuryou').val(1); }
  9869. \t\t\tif(parseInt(\$('#suuryou').val()) > 100){ \$('#suuryou').val(100); }
  9870. \t\t\t\$('#quantity').val(1);
  9871. \t\t\tmitsumori_simulation('suuryou','suuryou');
  9872. \t\t}
  9873. \t\tfunction maisu(mai){
  9874. \t\t\t\$('#maisu').val(parseInt(\$('#maisu').val()) + mai);
  9875. \t\t\t// sale_type=4 (フェンス) は3枚未満不可、6 (芝生) は1枚から
  9876. \t\t\tvar minMai = (SALE_TYPE_ID == 4) ? 3 : 1;
  9877. \t\t\tif(parseInt(\$('#maisu').val()) < minMai){ \$('#maisu').val(minMai); }
  9878. \t\t\tif(parseInt(\$('#maisu').val()) > 100){ \$('#maisu').val(100); }
  9879. \t\t\t\$('#quantity').val(1);
  9880. \t\t\tmitsumori_simulation('maisu','maisu');
  9881. \t\t}
  9882. \t\t// タイプ2: セット数プルダウン連動
  9883. \t\tfunction madosetSelect(val){
  9884. \t\t\tvar v = parseInt(val);
  9885. \t\t\tif(v < 1) v = 1;
  9886. \t\t\tif(v > 20) v = 20;
  9887. \t\t\t\$('#set_count').val(v);
  9888. \t\t\t\$('#quantity').val(1);
  9889. \t\t\t\$('input[name=\"quantity\"]').val(1);
  9890. \t\t\tmitsumori_simulation('set','set_count');
  9891. \t\t}
  9892. \t\t// タイプ2: ±ボタン版(後方互換)
  9893. \t\tfunction madoset(mai){
  9894. \t\t\tvar current = parseInt(\$('#set_count').val()) || 1;
  9895. \t\t\tvar next = current + mai;
  9896. \t\t\tif(next < 1) next = 1;
  9897. \t\t\tif(next > 20) next = 20;
  9898. \t\t\t\$('#set_count').val(next);
  9899. \t\t\tmadosetSelect(next);
  9900. \t\t}
  9901. \t\t// タイプ5: ステップ・フェンス選択値を mitsumori_json に保存するためのグローバル変数
  9902. \t\tvar deck_step = \"{% if mitsumori_json and mitsumori_json.deck_step is defined %}{{ mitsumori_json.deck_step|default('不要') }}{% else %}不要{% endif %}\";
  9903. \t\tvar deck_fence = \"{% if mitsumori_json and mitsumori_json.deck_fence is defined %}{{ mitsumori_json.deck_fence|default('不要') }}{% else %}不要{% endif %}\";
  9904. \t\t// PDF出力: モーダルの mitsumori_json をフォームに同期してから送信
  9905. \t\tfunction syncPdfJson(){
  9906. \t\t\tvar jsonVal = \$('#mitsumori_json').val();
  9907. \t\t\t\$('#pdf_mitsumori_json').val(jsonVal);
  9908. \t\t}
  9909. \t\t// タイプ9: 商品のみ購入
  9910. \t\tfunction quantityOnly(val){
  9911. \t\t\tvar current = parseInt(\$('#quantity_only').val()) || 1;
  9912. \t\t\tvar next = current + val;
  9913. \t\t\tif(next < 1) next = 1;
  9914. \t\t\t\$('#quantity_only').val(next);
  9915. \t\t\t\$('#quantity').val(next);
  9916. \t\t}
  9917.         // ===== スマホ用下部固定バーへの金額同期 =====
  9918.         // mitsumori_message と mitsumori_goukei を監視して下部バーを更新
  9919.         (function() {
  9920.             var msgTarget   = document.getElementById('mitsumori_message');
  9921.             var goukeiTarget = document.getElementById('mitsumori_goukei');
  9922.             var spPrice     = document.getElementById('sp-mitsumori-price');
  9923.             var spBtn       = document.querySelector('#sp-mitsumori-bar .sp-bar__btn');
  9924.             if (!spPrice || !spBtn) return;
  9925.             function syncBar() {
  9926.                 var msg    = msgTarget ? msgTarget.textContent : '';
  9927.                 var goukei = goukeiTarget ? goukeiTarget.textContent : '---円';
  9928.                 // メッセージが「〇〇を選択してください」の場合はメッセージを表示しボタンを非表示
  9929.                 if (msg.indexOf('選択してください') !== -1) {
  9930.                     spPrice.textContent = msg;
  9931.                     spPrice.style.fontSize = '13px';
  9932.                     spPrice.style.color    = '#888';
  9933.                     spBtn.style.display    = 'none';
  9934.                 } else {
  9935.                     // 価格確定時はボタンを表示
  9936.                     spPrice.textContent = goukei;
  9937.                     spPrice.style.fontSize = '18px';
  9938.                     spPrice.style.color    = '#c00';
  9939.                     spBtn.style.display    = 'block';
  9940.                 }
  9941.             }
  9942.             // 初期値を同期
  9943.             syncBar();
  9944.             // mitsumori_message の変化を監視
  9945.             if (msgTarget) {
  9946.                 new MutationObserver(syncBar).observe(
  9947.                     msgTarget, { childList: true, subtree: true, characterData: true }
  9948.                 );
  9949.             }
  9950.             // mitsumori_goukei の変化も監視
  9951.             if (goukeiTarget) {
  9952.                 new MutationObserver(syncBar).observe(
  9953.                     goukeiTarget, { childList: true, subtree: true, characterData: true }
  9954.                 );
  9955.             }
  9956.         })();
  9957.         // ===== スマホ用 お見積りの詳細 ボトムシート 開閉 =====
  9958.         // 現在の内訳カード(.mitsumori-card-pc .card-body)を複製して表示する。
  9959.         // 価格計算ロジックには触れず、その時点で表示中の内訳をそのまま見せる。
  9960.         // window に直接ぶら下げてスコープに依存せず onclick から呼べるようにする。
  9961.         window.openSpMitsumoriDetail = function () {
  9962.             var sheet = document.getElementById('sp-mitsumori-detail');
  9963.             var body  = document.getElementById('sp-detail-body');
  9964.             var src   = document.querySelector('.mitsumori-card-pc .card-body');
  9965.             if (!sheet || !body) return;
  9966.             body.innerHTML = '';
  9967.             if (src) {
  9968.                 // 複製し、重複 id を避けるため clone 側の id を除去する
  9969.                 var clone = src.cloneNode(true);
  9970.                 var ided = clone.querySelectorAll('[id]');
  9971.                 for (var i = 0; i < ided.length; i++) { ided[i].removeAttribute('id'); }
  9972.                 body.appendChild(clone);
  9973.             }
  9974.             sheet.classList.add('is-open');
  9975.             sheet.setAttribute('aria-hidden', 'false');
  9976.             document.body.style.overflow = 'hidden';
  9977.         };
  9978.         window.closeSpMitsumoriDetail = function () {
  9979.             var sheet = document.getElementById('sp-mitsumori-detail');
  9980.             if (!sheet) return;
  9981.             sheet.classList.remove('is-open');
  9982.             sheet.setAttribute('aria-hidden', 'true');
  9983.             document.body.style.overflow = '';
  9984.         };
  9985.         // ===== 現在のお見積り額: 折りたたみトグルボタンのテキスト切り替え =====
  9986.         (function() {
  9987.             var card = document.querySelector('.mitsumori-card-pc');
  9988.             var btn  = document.querySelector('.btn-mitsumori-toggle .toggle-icon');
  9989.             if (!card || !btn) return;
  9990.             // MutationObserverでcollapsed-cardクラスの変化を監視
  9991.             new MutationObserver(function() {
  9992.                 if (card.classList.contains('collapsed-card')) {
  9993.                     btn.textContent = '▼ 詳細';
  9994.                 } else {
  9995.                     btn.textContent = '▲ 閉じる';
  9996.                 }
  9997.             }).observe(card, { attributes: true, attributeFilter: ['class'] });
  9998.         })();
  9999.         // ===== エリア案内: スマホのみタップで展開 =====
  10000.         (function() {
  10001.             var notice = document.querySelector('.ec-areaNotice');
  10002.             if (!notice) return;
  10003.             notice.addEventListener('click', function(e) {
  10004.                 if (window.innerWidth > 767) return;
  10005.                 // リンククリック時は展開/折りたたみせずリンク遷移
  10006.                 if (e.target.tagName === 'A') return;
  10007.                 notice.classList.toggle('is-open');
  10008.             });
  10009.         })();
  10010.     </script>
  10011.     <script type=\"application/ld+json\">
  10012.     {
  10013.         \"@context\": \"https://schema.org/\",
  10014.         \"@type\": \"Product\",
  10015.         \"name\": \"{{ Product.name }}\",
  10016.         \"image\": [
  10017.             {% for img in Product.ProductImage %}
  10018.                 \"{{ app.request.schemeAndHttpHost }}{{ asset(img, 'save_image') }}\"{% if not loop.last %},{% endif %}
  10019.             {% else %}
  10020.                 \"{{ app.request.schemeAndHttpHost }}{{ asset(''|no_image_product, 'save_image') }}\"
  10021.             {% endfor %}
  10022.         ],
  10023.         \"description\": \"{{ Product.description_list | default(Product.description_detail) | replace({'\\n': '', '\\r': ''}) | slice(0,300) }}\",
  10024.         {% if Product.code_min %}
  10025.         \"sku\": \"{{ Product.code_min }}\",
  10026.         {% endif %}
  10027.         \"offers\": {
  10028.             \"@type\": \"Offer\",
  10029.             \"url\": \"{{ url('product_detail', {'id': Product.id}) }}\",
  10030.             \"priceCurrency\": \"{{ eccube_config.currency }}\",
  10031.             \"price\": {{ Product.getPrice02IncTaxMin ? Product.getPrice02IncTaxMin : 0}},
  10032.             \"availability\": \"{{ Product.stock_find ? \"InStock\" : \"OutOfStock\" }}\"
  10033.         }
  10034.     }
  10035.     </script>
  10036. {% endblock %}
  10037. {% block main %}
  10038.     {# option1 / option2 ラベルをカテゴリ別に決定 (sh=31, rd=43, mo=15) - block scope のため main 側でも再定義 #}
  10039.     {% set option1_label = 'オプション1' %}
  10040.     {% set option2_label = 'オプション2' %}
  10041.     {# rd(玄関ドア, cat43) は素材(m)が開き方+ランマを内包し option1(ランマ)/option2(タイプ) が
  10042.        完全な冗長軸のため、素材のみ「開き方」として表示し option1/option2 の選択 UI は抑制する。
  10043.        価格マッチングは m + カラーで一意に決まり、未選択 option は fallback が無視するため影響なし。 #}
  10044.     {% set is_cat43 = false %}
  10045.     {% if Product.ProductCategories is not empty %}
  10046.         {% for pcat in Product.ProductCategories %}
  10047.             {% if pcat.category_id == 31 %}{% set option1_label = 'サイズプリセット' %}{% set option2_label = '駆動方式' %}{% endif %}
  10048.             {% if pcat.category_id == 43 %}{% set option1_label = 'ランマ' %}{% set option2_label = 'タイプ' %}{% set is_cat43 = true %}{% endif %}
  10049.             {% if pcat.category_id == 15 %}{% set option1_label = '棚タイプ' %}{% endif %}
  10050.             {% if pcat.category_id == 17 %}{% set option1_label = '窓タイプ' %}{% endif %}
  10051.         {% endfor %}
  10052.     {% endif %}
  10053.     <div class=\"ec-productRole\" style=\"margin-top:20px;\">
  10054.         <div class=\"ec-grid2\">
  10055.             <div class=\"ec-grid2__cell\">
  10056.                 <div class=\"ec-sliderItemRole\">
  10057. \t                {# 商品名 + ブランド名 + SNSシェア #}
  10058. \t                <div class=\"ec-productRole__title\">
  10059. \t                    <div class=\"ec-productRole__titleRow\">
  10060. \t                        <h2 class=\"ec-headingTitle\">{{ Product.name }}</h2>
  10061. \t                        <div class=\"ec-share-inline\">
  10062. \t                            <a href=\"https://twitter.com/share?url={{ app.request.uri|url_encode }}&text={{ Product.name|url_encode }}\"
  10063. \t                               class=\"share-twitter\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"Xでシェア\">
  10064. \t                                <svg viewBox=\"0 0 24 24\" style=\"width:15px;height:15px;fill:#fff;\"><path d=\"M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-4.714-6.231-5.401 6.231H2.74l7.73-8.835L1.254 2.25H8.08l4.254 5.622L18.244 2.25zm-1.161 17.52h1.833L7.084 4.126H5.117z\"/></svg>
  10065. \t                            </a>
  10066. \t                            <a href=\"https://www.instagram.com/\" class=\"share-facebook\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"Instagram\">
  10067. \t                                <svg viewBox=\"0 0 24 24\" style=\"width:15px;height:15px;fill:#fff;\"><path d=\"M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zM12 0C8.741 0 8.333.014 7.053.072 2.695.272.273 2.69.073 7.052.014 8.333 0 8.741 0 12c0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98C8.333 23.986 8.741 24 12 24c3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98C15.668.014 15.259 0 12 0zm0 5.838a6.162 6.162 0 100 12.324 6.162 6.162 0 000-12.324zM12 16a4 4 0 110-8 4 4 0 010 8zm6.406-11.845a1.44 1.44 0 100 2.881 1.44 1.44 0 000-2.881z\"/></svg>
  10068. \t                            </a>
  10069. \t                            <a href=\"https://social-plugins.line.me/lineit/share?url={{ app.request.uri|url_encode }}\"
  10070. \t                               class=\"share-line\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"LINEでシェア\">
  10071. \t                                <i class=\"fab fa-line\"></i>
  10072. \t                            </a>
  10073. \t                        </div>
  10074. \t                    </div>
  10075. \t                </div>
  10076.                     {% if BaseInfo.option_favorite_product %}
  10077.                      <div style=\"position:relative;top: 20px;left: 10px;z-index:100;\">
  10078. \t\t\t\t\t\t{% if is_favorite == false %}
  10079.                         <form action=\"{{ url('product_add_favorite', {id:Product.id}) }}\" method=\"post\">
  10080.                            <button type=\"submit\" id=\"favorite\" class=\"favorite\">&#9825;</button>
  10081.                         </form>
  10082.                         {% else %}
  10083.                         <form action=\"{{ url('product_add_favorite', {id:Product.id}) }}\" method=\"post\">
  10084.                            <button type=\"submit\" id=\"favorite\" class=\"favorite\" style=\"color:red;\">&#9829;</button>
  10085.                         </form>
  10086.                         {% endif %}
  10087.                      </div>
  10088.                     {% endif %}
  10089.                     <div class=\"item_visual\">
  10090.                         {% for ProductImage in Product.ProductImage %}
  10091.                             <div class=\"slide-item\">
  10092.                                 <a class=\"js-zoom\" href=\"{{ asset(ProductImage, 'save_image') }}\" aria-label=\"{{ loop.first ? Product.name : '' }}\">
  10093.                                     <img src=\"{{ asset(ProductImage, 'save_image') }}\" alt=\"{{ loop.first ? Product.name : '' }}\" width=\"550\" height=\"550\" style=\"max-height: 400px;\"{% if loop.index > 1 %} loading=\"lazy\"{% endif %}>
  10094.                                 </a>
  10095.                             </div>
  10096.                         {% else %}
  10097.                             <div class=\"slide-item\"><img src=\"{{ asset(''|no_image_product, 'save_image') }}\" alt=\"{{ Product.name }}\" width=\"550\" height=\"550\" style=\"max-height: 400px;\"></div>
  10098.                         {% endfor %}
  10099.                     </div>
  10100.                     <div class=\"item_nav\">
  10101.                         {% for ProductImage in Product.ProductImage %}
  10102.                             <div class=\"slideThumb\" data-index=\"{{ loop.index0 }}\"><img src=\"{{ asset(ProductImage, 'save_image') }}\" alt=\"\" width=\"80\" height=\"80\" loading=\"lazy\"></div>
  10103.                         {% endfor %}
  10104.                     </div>
  10105.                 </div>
  10106.                     {# ===== 施工エリア案内(見積シミュレーションの下)===== #}
  10107.                     <div class=\"ec-areaNotice\" style=\"margin-top:16px;margin-right:10px;\">
  10108.                         <div class=\"ec-areaNotice__inner\">
  10109.                             <div class=\"ec-areaNotice__icon\">📍</div>
  10110.                             <div class=\"ec-areaNotice__body\">
  10111.                                 <p class=\"ec-areaNotice__title\">施工対応エリアについて</p>
  10112.                                 <div class=\"ec-areaNotice__detail\">
  10113.                                     <p class=\"ec-areaNotice__text\">
  10114.                                         当店の施工サービスは、<strong>山梨県全域</strong>および<br>
  10115.                                         <strong>諏訪エリア(諏訪市・岡谷市・茅野市・諏訪郡)</strong>を対象としております。<br>
  10116.                                         上記エリア外のお客様には、商品のみのご購入が可能でございます。<br>
  10117.                                         ご不明な点がございましたら、お気軽にお問い合わせください。
  10118.                                     </p>
  10119.                                     <a class=\"ec-areaNotice__link\" href=\"{{ url('contact') }}\">エリア外のお客様・ご相談はこちら →</a>
  10120.                                 </div>
  10121.                             </div>
  10122.                         </div>
  10123.                     </div>
  10124.             </div>
  10125.             <div class=\"ec-grid2__cell2\">
  10126.                 <div class=\"ec-productRole__profile\" >
  10127.                     {# 関連カテゴリ (DIY=21 / 石材=28 / 照明=44 は非表示要件のため除外) #}
  10128.                     {% set hidden_cat_ids = [21, 28, 44] %}
  10129.                     {% if Product.ProductCategories is not empty %}
  10130.                         <div class=\"ec-productRole__category\" style=\"padding:10px 0;\">
  10131.                             {% for ProductCategory in Product.ProductCategories %}
  10132.                                 {% if ProductCategory.Category.id not in hidden_cat_ids %}
  10133.                                 <ul>
  10134.                                     <li>
  10135.                                         {% for Category in ProductCategory.Category.path %}
  10136.                                             <a href=\"{{ url('product_list') }}?category_id={{ Category.id }}\">{{ Category.name }}</a> {%- if loop.last == false %}
  10137.                                             <span>></span>{% endif -%}
  10138.                                         {% endfor %}
  10139.                                     </li>
  10140.                                 </ul>
  10141.                                 {% endif %}
  10142.                             {% endfor %}
  10143.                         </div>
  10144.                     {% endif %}
  10145.                     {# 販売価格 #}
  10146.                     <div class=\"ec-productRole__price\">
  10147. \t\t\t\t\t\t<span style=\"color:black;font-size:15px;\">工事費込み価格</span>
  10148.                         {% if Product.hasProductClass -%}
  10149.                             {% if Product.getPrice02IncTaxMin == Product.getPrice02IncTaxMax %}
  10150.                                 <div class=\"ec-price\">
  10151.                                     <span id=\"price02-display\" class=\"ec-price__price price02-default\">{{ Product.getPrice02IncTaxMin|price }}</span>
  10152.                                     <span class=\"ec-price__tax\">({{ '税込'|trans }})~</span>
  10153.                                 </div>
  10154.                             {% else %}
  10155.                                 <div class=\"ec-price\">
  10156.                                     <span id=\"price02-display\" class=\"ec-price__price price02-default\">{{ Product.getPrice02IncTaxMin|price }} ~ {{ Product.getPrice02IncTaxMax|price }}</span>
  10157.                                     <span class=\"ec-price__tax\">({{ '税込'|trans }})</span>
  10158.                                 </div>
  10159.                             {% endif %}
  10160.                         {% else %}
  10161.                             <div class=\"ec-price\">
  10162.                                 <span id=\"price02-display\" class=\"ec-price__price\">{{ Product.getPrice02IncTaxMin|price }}</span>
  10163.                                     <span class=\"ec-price__tax\">({{ '税込'|trans }})~</span>
  10164.                             </div>
  10165.                         {% endif %}
  10166.                     </div>
  10167.                     {# タグ #}
  10168.                     <ul class=\"ec-productRole__tags\">
  10169.                         {% for Tag in Product.Tags %}
  10170.                             <li class=\"ec-productRole__tag tag_{{ Tag.id }}\">{{ Tag }}</li>
  10171.                         {% endfor %}
  10172.                     </ul>
  10173.                     {# 商品コード #}
  10174.                     {% if Product.code_min is not empty %}
  10175.                         <div class=\"ec-productRole__code\">
  10176.                             {{ '商品コード'|trans }}: <span class=\"product-code-default\">{{ Product.code_min }}{% if Product.code_min != Product.code_max %} ~ {{ Product.code_max }}{% endif %}</span>
  10177.                         </div>
  10178.                     {% endif %}
  10179.                     <div class=\"ec-productRole__description\">
  10180. \t\t\t\t        <div class=\"ec-rectHeading\">
  10181. \t\t\t\t            <h4>製品情報</h4>
  10182. \t\t\t\t        </div>
  10183. \t\t\t\t\t\t{{ Product.sales_infomation|raw|nl2br }}
  10184.                     </div>
  10185. \t\t\t\t\t<div class=\"card card-danger\" style=\"clear:both;margin:1px;\">
  10186. \t\t\t\t\t  <div class=\"card-header\">
  10187. \t\t\t\t\t    <h3 class=\"card-title\">見積シミュレーション</h3>
  10188. \t\t\t\t\t  </div>
  10189. \t\t\t\t\t  <div class=\"card-body p-2\">
  10190.                         {% set related_image = getProduct_field(Product.id,\"related_image\") %}
  10191.                         {# related_image は配列: [\"1段目画像あり\",\"2段目画像あり\",\"3段目画像あり\"] のうち該当するものが格納 #}
  10192.                         {% set img1 = related_image and (\"1段目画像あり\" in related_image) %}
  10193.                         {% set img2 = related_image and (\"2段目画像あり\" in related_image) %}
  10194.                         {% set img3 = related_image and (\"3段目画像あり\" in related_image) %}
  10195.                         {% set img4 = related_image and (\"4段目画像あり\" in related_image) %}
  10196. \t\t\t\t\t    {% set type1 = getProduct_field(Product.id,\"related_name1\") %}
  10197. \t\t\t\t\t\t{% set type2 = getProduct_field(Product.id,\"related_name2\") %}
  10198. \t\t\t\t\t\t{% set type3 = getProduct_field(Product.id,\"related_name3\") %}
  10199. \t\t\t\t\t\t{% set type4 = getProduct_field(Product.id,\"related_name4\") %}
  10200. \t\t\t\t\t\t{% set hasRelated = (type1 and related_product1 and related_product1|length)
  10201. \t\t\t\t\t\t                 or (type2 and related_product2 and related_product2|length)
  10202. \t\t\t\t\t\t                 or (type3 and related_product3 and related_product3|length)
  10203. \t\t\t\t\t\t                 or (type4 and related_product4 and related_product4|length) %}
  10204. \t\t\t\t\t\t{% if hasRelated %}
  10205. \t\t\t\t\t\t    <div class=\"row\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\"><label class=\"col-12 col-form-label\">この商品のタイプを選択してください。</label></div>
  10206. \t\t\t\t\t\t{% endif %}
  10207. \t\t\t\t\t\t{# ===== 1段目 ===== #}
  10208. \t\t\t\t\t\t{% if type1 and related_product1 and related_product1|length %}
  10209. \t\t\t\t\t\t<div class=\"form-group mt-3 pb-3\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10210. \t\t\t\t\t\t  <div class=\"rp-section-label\">{{ type1 }}{% if img1 and base_select1 %}: <span>{{ base_select1 }}</span>{% endif %}</div>
  10211. \t\t\t\t\t\t  {% if img1 %}
  10212. \t\t\t\t\t\t    {# --- 画像付きカード --- #}
  10213. \t\t\t\t\t\t    <div class=\"rp-card-group\">
  10214. \t\t\t\t\t\t      {% for rp_id, rp_name in related_product1 %}
  10215. \t\t\t\t\t\t        <a class=\"rp-card{% if base_select1 == rp_name %} is-selected{% endif %}\" href=\"/products/detail/{{ rp_id }}\">
  10216. \t\t\t\t\t\t          <img class=\"rp-card__image\"
  10217. \t\t\t\t\t\t               src=\"{{ (related_image_obj[rp_id] is defined and related_image_obj[rp_id]) ? asset(related_image_obj[rp_id], 'save_image') : asset(''|no_image_product, 'save_image') }}\"
  10218. \t\t\t\t\t\t               alt=\"{{ rp_name }}\"
  10219. \t\t\t\t\t\t               width=\"120\" height=\"120\" loading=\"lazy\"
  10220. \t\t\t\t\t\t               onerror=\"this.style.display='none';this.nextElementSibling.style.display='flex';\">
  10221. \t\t\t\t\t\t          <div class=\"rp-card__placeholder\" style=\"display:none;\">📦</div>
  10222. \t\t\t\t\t\t          <span class=\"rp-card__name\">{{ rp_name }}</span>
  10223. \t\t\t\t\t\t        </a>
  10224. \t\t\t\t\t\t      {% endfor %}
  10225. \t\t\t\t\t\t    </div>
  10226. \t\t\t\t\t\t  {% else %}
  10227. \t\t\t\t\t\t    {# --- ボタン式ラジオ --- #}
  10228. \t\t\t\t\t\t    <div class=\"rp-btn-group\">
  10229. \t\t\t\t\t\t      {% for rp_id, rp_name in related_product1 %}
  10230. \t\t\t\t\t\t        <a class=\"rp-btn{% if base_select1 == rp_name %} is-selected{% endif %}\" href=\"/products/detail/{{ rp_id }}\">
  10231. \t\t\t\t\t\t          {{ rp_name }}
  10232. \t\t\t\t\t\t        </a>
  10233. \t\t\t\t\t\t      {% endfor %}
  10234. \t\t\t\t\t\t    </div>
  10235. \t\t\t\t\t\t  {% endif %}
  10236. \t\t\t\t\t\t</div>
  10237. \t\t\t\t\t\t{% endif %}
  10238. \t\t\t\t\t\t{# ===== 2段目 ===== #}
  10239. \t\t\t\t\t\t{% if type2 and related_product2 and related_product2|length %}
  10240. \t\t\t\t\t\t<div class=\"form-group mt-3 pb-3\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10241. \t\t\t\t\t\t  <div class=\"rp-section-label\">{{ type2 }}{% if img2 and base_select2 %}: <span>{{ base_select2 }}</span>{% endif %}</div>
  10242. \t\t\t\t\t\t  {% if img2 %}
  10243. \t\t\t\t\t\t    <div class=\"rp-card-group\">
  10244. \t\t\t\t\t\t      {% for rp_id, rp_name in related_product2 %}
  10245. \t\t\t\t\t\t        <a class=\"rp-card{% if base_select2 == rp_name %} is-selected{% endif %}\" href=\"/products/detail/{{ rp_id }}\">
  10246. \t\t\t\t\t\t          <img class=\"rp-card__image\"
  10247. \t\t\t\t\t\t               src=\"{{ (related_image_obj[rp_id] is defined and related_image_obj[rp_id]) ? asset(related_image_obj[rp_id], 'save_image') : asset(''|no_image_product, 'save_image') }}\"
  10248. \t\t\t\t\t\t               alt=\"{{ rp_name }}\"
  10249. \t\t\t\t\t\t               width=\"120\" height=\"120\" loading=\"lazy\"
  10250. \t\t\t\t\t\t               onerror=\"this.style.display='none';this.nextElementSibling.style.display='flex';\">
  10251. \t\t\t\t\t\t          <div class=\"rp-card__placeholder\" style=\"display:none;\">📦</div>
  10252. \t\t\t\t\t\t          <span class=\"rp-card__name\">{{ rp_name }}</span>
  10253. \t\t\t\t\t\t        </a>
  10254. \t\t\t\t\t\t      {% endfor %}
  10255. \t\t\t\t\t\t    </div>
  10256. \t\t\t\t\t\t  {% else %}
  10257. \t\t\t\t\t\t    <div class=\"rp-btn-group\">
  10258. \t\t\t\t\t\t      {% for rp_id, rp_name in related_product2 %}
  10259. \t\t\t\t\t\t        <a class=\"rp-btn{% if base_select2 == rp_name %} is-selected{% endif %}\" href=\"/products/detail/{{ rp_id }}\">
  10260. \t\t\t\t\t\t          {{ rp_name }}
  10261. \t\t\t\t\t\t        </a>
  10262. \t\t\t\t\t\t      {% endfor %}
  10263. \t\t\t\t\t\t    </div>
  10264. \t\t\t\t\t\t  {% endif %}
  10265. \t\t\t\t\t\t</div>
  10266. \t\t\t\t\t\t{% endif %}
  10267. \t\t\t\t\t\t{# ===== 3段目 ===== #}
  10268. \t\t\t\t\t\t{% if type3 and related_product3 and related_product3|length %}
  10269. \t\t\t\t\t\t<div class=\"form-group mt-3 pb-3\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10270. \t\t\t\t\t\t  <div class=\"rp-section-label\">{{ type3 }}{% if img3 and base_select3 %}: <span>{{ base_select3 }}</span>{% endif %}</div>
  10271. \t\t\t\t\t\t  {% if img3 %}
  10272. \t\t\t\t\t\t    <div class=\"rp-card-group\">
  10273. \t\t\t\t\t\t      {% for rp_id, rp_name in related_product3 %}
  10274. \t\t\t\t\t\t        <a class=\"rp-card{% if base_select3 == rp_name %} is-selected{% endif %}\" href=\"/products/detail/{{ rp_id }}\">
  10275. \t\t\t\t\t\t          <img class=\"rp-card__image\"
  10276. \t\t\t\t\t\t               src=\"{{ (related_image_obj[rp_id] is defined and related_image_obj[rp_id]) ? asset(related_image_obj[rp_id], 'save_image') : asset(''|no_image_product, 'save_image') }}\"
  10277. \t\t\t\t\t\t               alt=\"{{ rp_name }}\"
  10278. \t\t\t\t\t\t               width=\"120\" height=\"120\" loading=\"lazy\"
  10279. \t\t\t\t\t\t               onerror=\"this.style.display='none';this.nextElementSibling.style.display='flex';\">
  10280. \t\t\t\t\t\t          <div class=\"rp-card__placeholder\" style=\"display:none;\">📦</div>
  10281. \t\t\t\t\t\t          <span class=\"rp-card__name\">{{ rp_name }}</span>
  10282. \t\t\t\t\t\t        </a>
  10283. \t\t\t\t\t\t      {% endfor %}
  10284. \t\t\t\t\t\t    </div>
  10285. \t\t\t\t\t\t  {% else %}
  10286. \t\t\t\t\t\t    <div class=\"rp-btn-group\">
  10287. \t\t\t\t\t\t      {% for rp_id, rp_name in related_product3 %}
  10288. \t\t\t\t\t\t        <a class=\"rp-btn{% if base_select3 == rp_name %} is-selected{% endif %}\" href=\"/products/detail/{{ rp_id }}\">
  10289. \t\t\t\t\t\t          {{ rp_name }}
  10290. \t\t\t\t\t\t        </a>
  10291. \t\t\t\t\t\t      {% endfor %}
  10292. \t\t\t\t\t\t    </div>
  10293. \t\t\t\t\t\t  {% endif %}
  10294. \t\t\t\t\t\t</div>
  10295. \t\t\t\t\t\t{% endif %}
  10296. \t\t\t\t\t\t{# ===== 4段目 ===== #}
  10297. \t\t\t\t\t\t{% if type4 and related_product4 and related_product4|length %}
  10298. \t\t\t\t\t\t<div class=\"form-group mt-3 pb-3\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10299. \t\t\t\t\t\t  <div class=\"rp-section-label\">{{ type4 }}{% if img4 and base_select4 %}: <span>{{ base_select4 }}</span>{% endif %}</div>
  10300. \t\t\t\t\t\t  {% if img4 %}
  10301. \t\t\t\t\t\t    {# --- 画像付きカード --- #}
  10302. \t\t\t\t\t\t    <div class=\"rp-card-group\">
  10303. \t\t\t\t\t\t      {% for rp_id, rp_name in related_product4 %}
  10304. \t\t\t\t\t\t        <a class=\"rp-card{% if base_select4 == rp_name %} is-selected{% endif %}\" href=\"/products/detail/{{ rp_id }}\">
  10305. \t\t\t\t\t\t          <img class=\"rp-card__image\"
  10306. \t\t\t\t\t\t               src=\"{{ (related_image_obj[rp_id] is defined and related_image_obj[rp_id]) ? asset(related_image_obj[rp_id], 'save_image') : asset(''|no_image_product, 'save_image') }}\"
  10307. \t\t\t\t\t\t               alt=\"{{ rp_name }}\" width=\"120\" height=\"120\" loading=\"lazy\">
  10308. \t\t\t\t\t\t          <span class=\"rp-card__label\">{{ rp_name }}</span>
  10309. \t\t\t\t\t\t        </a>
  10310. \t\t\t\t\t\t      {% endfor %}
  10311. \t\t\t\t\t\t    </div>
  10312. \t\t\t\t\t\t  {% else %}
  10313. \t\t\t\t\t\t    {# --- ボタン式ラジオ --- #}
  10314. \t\t\t\t\t\t    <div class=\"rp-btn-group\">
  10315. \t\t\t\t\t\t      {% for rp_id, rp_name in related_product4 %}
  10316. \t\t\t\t\t\t        <a class=\"rp-btn{% if base_select4 == rp_name %} is-selected{% endif %}\" href=\"/products/detail/{{ rp_id }}\">
  10317. \t\t\t\t\t\t          {{ rp_name }}
  10318. \t\t\t\t\t\t        </a>
  10319. \t\t\t\t\t\t      {% endfor %}
  10320. \t\t\t\t\t\t    </div>
  10321. \t\t\t\t\t\t  {% endif %}
  10322. \t\t\t\t\t\t</div>
  10323. \t\t\t\t\t\t{% endif %}
  10324. \t\t\t\t\t    {# ガレージ等で全オプション空のときに見出しのみ表示される事象を回避.
  10325. \t\t\t\t\t       色 / 寸法 / 素材 / option1/2 / op_data いずれかに「描画される」要素がある場合のみ
  10326. \t\t\t\t\t       「この商品のオプションを選択してください。」見出しを表示する.
  10327. \t\t\t\t\t       op_data は cg=9 で「残土」 / gs=27 で「撤去」「残土」を後段ループで
  10328. \t\t\t\t\t       hide するため、単純な op|length > 0 では「見出しだけ残る」事象が
  10329. \t\t\t\t\t       wh / cg の一部商品で発生していた. 描画される entry を事前カウントする. #}
  10330. \t\t\t\t\t    {% set is_gs_h = false %}
  10331. \t\t\t\t\t    {% set is_cg_h = false %}
  10332. \t\t\t\t\t    {% if Product.ProductCategories is not empty %}
  10333. \t\t\t\t\t        {% for pc_h in Product.ProductCategories %}
  10334. \t\t\t\t\t            {% if pc_h.category_id == 27 %}{% set is_gs_h = true %}{% endif %}
  10335. \t\t\t\t\t            {% if pc_h.category_id == 9  %}{% set is_cg_h = true %}{% endif %}
  10336. \t\t\t\t\t        {% endfor %}
  10337. \t\t\t\t\t    {% endif %}
  10338. \t\t\t\t\t    {% set visible_op_count = 0 %}
  10339. \t\t\t\t\t    {% if op and op|length %}
  10340. \t\t\t\t\t        {% for opi in op %}
  10341. \t\t\t\t\t            {% if opi['name'] %}
  10342. \t\t\t\t\t                {% set _hide_h = false %}
  10343. \t\t\t\t\t                {% if is_gs_h and (opi['name'] matches '/撤去/' or opi['name'] matches '/残土/') %}{% set _hide_h = true %}{% endif %}
  10344. \t\t\t\t\t                {% if is_cg_h and opi['name'] matches '/残土/' %}{% set _hide_h = true %}{% endif %}
  10345. \t\t\t\t\t                {% if not _hide_h %}{% set visible_op_count = visible_op_count + 1 %}{% endif %}
  10346. \t\t\t\t\t            {% endif %}
  10347. \t\t\t\t\t        {% endfor %}
  10348. \t\t\t\t\t    {% endif %}
  10349. \t\t\t\t\t    {% set has_any_option =
  10350. \t\t\t\t\t        (color and color|length and ProductClass.SaleType.id != 3)
  10351. \t\t\t\t\t        or (p_w and p_w|length and p_w|join != \"\")
  10352. \t\t\t\t\t        or (p_d and p_d|length and p_d|join != \"\")
  10353. \t\t\t\t\t        or (p_h and p_h|length and p_h|join != \"\")
  10354. \t\t\t\t\t        or (p_m and p_m|length and p_m|join != \"\")
  10355. \t\t\t\t\t        or (p_option1 and p_option1|length and p_option1|join != \"\")
  10356. \t\t\t\t\t        or (p_option2 and p_option2|length and p_option2|join != \"\")
  10357. \t\t\t\t\t        or ProductClass.SaleType.id in [2, 5, 6, 7, 9]
  10358. \t\t\t\t\t    %}
  10359. \t\t\t\t\t    {% if has_any_option %}
  10360. \t\t\t\t\t    <div class=\"row\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\"><label class=\"col-12 col-form-label\">この商品のオプションを選択してください。</label></div>
  10361. \t\t\t\t\t    {% endif %}
  10362.                         {# sale_type=2 (補助金窓) はタイプごとに個別カラー選択するため共通カラーは非表示 #}
  10363.                         {% if color and color|length and ProductClass.SaleType.id != 3 and ProductClass.SaleType.id != 2 %}
  10364.                         <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10365.                           <div class=\"rp-section-label\">カラー{% if mitsumori_json and mitsumori_json.pc %}: <span>{{ mitsumori_json.pc }}</span>{% endif %}</div>
  10366.                           <div class=\"opt-btn-group\">
  10367.                             {% set idx = 0 %}
  10368.                             {% for cc in color %}{% if cc and cc['name'] %}{% set idx = idx + 1 %}
  10369.                               {% set has_img = cc['img'] is defined and cc['img'] is not empty %}
  10370.                               <label class=\"opt-btn{% if has_img %} opt-btn--with-image{% endif %}{% if (mitsumori_json and mitsumori_json.pc == cc['name']) or color|length == 1 %} is-selected{% endif %}\"
  10371.                                      onclick=\"mitsumori_simulation_val('pc', '{{ cc['name']|e('js') }}');\">
  10372.                                 <input type=\"radio\" name=\"color\" id=\"cc_{{ idx }}\" value=\"{{ cc['name'] }}\"
  10373.                                        {% if (mitsumori_json and mitsumori_json.pc == cc['name']) or color|length == 1 %}checked{% endif %}>
  10374.                                 {% if has_img %}
  10375.                                   <img src=\"{{ cc['img'] }}\" alt=\"{{ cc['name'] }}\" class=\"opt-btn__img\"
  10376.                                        onerror=\"this.parentNode.classList.remove('opt-btn--with-image'); this.remove();\">
  10377.                                   <span class=\"opt-btn__name\">{{ cc['name'] }}</span>
  10378.                                 {% else %}
  10379.                                   {{ cc['name'] }}
  10380.                                 {% endif %}
  10381.                               </label>
  10382.                             {% endif %}{% endfor %}
  10383.                           </div>
  10384.                         </div>
  10385.                         {% endif %}
  10386.                         {# sale_type=2 (補助金窓) はタイプごとに個別幅選択するため共通幅は非表示.
  10387.                            tf (人工芝, sale_type=6) は専用の「芝の幅」+「施工サイズ」UI を下部に持つため、
  10388.                            汎用の 幅/奥行/高さ は描画しない (両方出すと name=\"pw\"/\"ph\" が重複し、
  10389.                            片方を選ぶともう片方の選択が外れる顧客指摘あり). #}
  10390.                         {% if p_w and p_w|length and p_w|join != \"\" and ProductClass.SaleType.id not in [2, 3, 6] %}
  10391.                         <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10392.                           <div class=\"rp-section-label\">幅{% if mitsumori_json and mitsumori_json.pw %}: <span>{{ mitsumori_json.pw }}</span>{% endif %}</div>
  10393.                           <div class=\"opt-btn-group\">
  10394.                             {% set idx = 0 %}
  10395.                             {% for pw in p_w %}{% if pw %}{% set idx = idx + 1 %}
  10396.                               <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.pw == pw) or p_w|length == 1 %} is-selected{% endif %}\"
  10397.                                      onclick=\"mitsumori_simulation_val('pw', '{{ pw|e('js') }}');\">
  10398.                                 <input type=\"radio\" name=\"pw\" id=\"pw_{{ idx }}\" value=\"{{ pw }}\"
  10399.                                        {% if (mitsumori_json and mitsumori_json.pw == pw) or p_w|length == 1 %}checked{% endif %}>
  10400.                                 {{ pw }}
  10401.                               </label>
  10402.                             {% endif %}{% endfor %}
  10403.                           </div>
  10404.                         </div>
  10405.                         {% endif %}
  10406.                         {% if p_d and p_d|length and p_d|join != \"\" and ProductClass.SaleType.id not in [3, 6] %}
  10407.                         <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10408.                           <div class=\"rp-section-label\">奥行き{% if mitsumori_json and mitsumori_json.pd %}: <span>{{ mitsumori_json.pd }}</span>{% endif %}</div>
  10409.                           <div class=\"opt-btn-group\">
  10410.                             {% set idx = 0 %}
  10411.                             {% for pd in p_d %}{% if pd %}{% set idx = idx + 1 %}
  10412.                               <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.pd == pd) or p_d|length == 1 %} is-selected{% endif %}\"
  10413.                                      onclick=\"mitsumori_simulation_val('pd', '{{ pd|e('js') }}');\">
  10414.                                 <input type=\"radio\" name=\"pd\" id=\"pd_{{ idx }}\" value=\"{{ pd }}\"
  10415.                                        {% if (mitsumori_json and mitsumori_json.pd == pd) or p_d|length == 1 %}checked{% endif %}>
  10416.                                 {{ pd }}
  10417.                               </label>
  10418.                             {% endif %}{% endfor %}
  10419.                           </div>
  10420.                         </div>
  10421.                         {% endif %}
  10422.                         {# sale_type=2 (補助金窓) はタイプごとに個別高さ選択するため共通高さは非表示.
  10423.                            sale_type=6 (人工芝) は専用 UI なので汎用高さは描画しない. #}
  10424.                         {% if p_h and p_h|length and p_h|join != \"\" and ProductClass.SaleType.id not in [2, 3, 6] %}
  10425.                         <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10426.                           <div class=\"rp-section-label\">高さ{% if mitsumori_json and mitsumori_json.ph %}: <span>{{ mitsumori_json.ph }}</span>{% endif %}</div>
  10427.                           <div class=\"opt-btn-group\">
  10428.                             {% set idx = 0 %}
  10429.                             {% for ph in p_h %}{% if ph %}{% set idx = idx + 1 %}
  10430.                               <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.ph == ph) or p_h|length == 1 %} is-selected{% endif %}\"
  10431.                                      onclick=\"mitsumori_simulation_val('ph', '{{ ph|e('js') }}');\">
  10432.                                 <input type=\"radio\" name=\"ph\" id=\"ph_{{ idx }}\" value=\"{{ ph }}\"
  10433.                                        {% if (mitsumori_json and mitsumori_json.ph == ph) or p_h|length == 1 %}checked{% endif %}>
  10434.                                 {{ ph }}
  10435.                               </label>
  10436.                             {% endif %}{% endfor %}
  10437.                           </div>
  10438.                         </div>
  10439.                         {% endif %}
  10440.                         {# sale_type=2 (補助金窓) はタイプごとに個別ガラス選択するため共通素材は非表示 #}
  10441.                         {% if p_m and p_m|length and p_m|join != \"\" and ProductClass.SaleType.id != 3 and ProductClass.SaleType.id != 2 %}
  10442.                         <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10443.                           <div class=\"rp-section-label\">{% if is_cat43 %}開き方{% else %}素材{% endif %}{% if mitsumori_json and mitsumori_json.pm %}: <span>{{ mitsumori_json.pm }}</span>{% endif %}</div>
  10444.                           <div class=\"opt-btn-group\">
  10445.                             {% set idx = 0 %}
  10446.                             {% for pm in p_m %}{% if pm %}{% set idx = idx + 1 %}
  10447.                               <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.pm == pm) or p_m|length == 1 %} is-selected{% endif %}\"
  10448.                                      onclick=\"mitsumori_simulation_val('pm', '{{ pm|e('js') }}');\">
  10449.                                 <input type=\"radio\" name=\"pm\" id=\"pm_{{ idx }}\" value=\"{{ pm }}\"
  10450.                                        {% if (mitsumori_json and mitsumori_json.pm == pm) or p_m|length == 1 %}checked{% endif %}>
  10451.                                 {{ pm }}
  10452.                               </label>
  10453.                             {% endif %}{% endfor %}
  10454.                           </div>
  10455.                         </div>
  10456.                         {% endif %}
  10457.                         {# option1 (sale_type 2 は専用 UI が下にあるため除外 / sale_type 3 は下部ブロックで描画 /
  10458.                            sale_type 4 = fe・ts は option1 が ct_unit_price (枚数増分の工事費単価) で
  10459.                            ユーザー選択肢ではなく計算用の内部値のため radio として表示しない. 値は
  10460.                            上の auto-init (p_option1|length == 1) で JS の option1 変数に埋め込み済み) #}
  10461.                         {% if p_option1 and p_option1|length and p_option1|join != \"\" and ProductClass.SaleType.id != 2 and ProductClass.SaleType.id != 3 and ProductClass.SaleType.id != 4 and not is_cat43 %}
  10462.                         <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10463.                           <div class=\"rp-section-label\">{{ option1_label }}{% if mitsumori_json and mitsumori_json.option1 is defined and mitsumori_json.option1 %}: <span>{{ mitsumori_json.option1 }}</span>{% endif %}</div>
  10464.                           <div class=\"opt-btn-group\">
  10465.                             {% set idx = 0 %}
  10466.                             {% for opt1 in p_option1 %}{% if opt1 %}{% set idx = idx + 1 %}
  10467.                               <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.option1 is defined and mitsumori_json.option1 == opt1) or p_option1|length == 1 %} is-selected{% endif %}\"
  10468.                                      onclick=\"mitsumori_simulation_val('option1', '{{ opt1|e('js') }}');\">
  10469.                                 <input type=\"radio\" name=\"option1\" id=\"option1_{{ idx }}\" value=\"{{ opt1 }}\"
  10470.                                        {% if (mitsumori_json and mitsumori_json.option1 is defined and mitsumori_json.option1 == opt1) or p_option1|length == 1 %}checked{% endif %}>
  10471.                                 {{ opt1 }}
  10472.                               </label>
  10473.                             {% endif %}{% endfor %}
  10474.                           </div>
  10475.                         </div>
  10476.                         {% endif %}
  10477.                         {# option2 #}
  10478.                         {% if p_option2 and p_option2|length and p_option2|join != \"\" and ProductClass.SaleType.id != 2 and ProductClass.SaleType.id != 3 and not is_cat43 %}
  10479.                         <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10480.                           <div class=\"rp-section-label\">{{ option2_label }}{% if mitsumori_json and mitsumori_json.option2 is defined and mitsumori_json.option2 %}: <span>{{ mitsumori_json.option2 }}</span>{% endif %}</div>
  10481.                           <div class=\"opt-btn-group\">
  10482.                             {% set idx = 0 %}
  10483.                             {% for opt2 in p_option2 %}{% if opt2 %}{% set idx = idx + 1 %}
  10484.                               <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.option2 is defined and mitsumori_json.option2 == opt2) or p_option2|length == 1 %} is-selected{% endif %}\"
  10485.                                      onclick=\"mitsumori_simulation_val('option2', '{{ opt2|e('js') }}');\">
  10486.                                 <input type=\"radio\" name=\"option2\" id=\"option2_{{ idx }}\" value=\"{{ opt2 }}\"
  10487.                                        {% if (mitsumori_json and mitsumori_json.option2 is defined and mitsumori_json.option2 == opt2) or p_option2|length == 1 %}checked{% endif %}>
  10488.                                 {{ opt2 }}
  10489.                               </label>
  10490.                             {% endif %}{% endfor %}
  10491.                           </div>
  10492.                         </div>
  10493.                         {% endif %}
  10494. \t\t\t\t\t\t<!-- 1: 施工見積(通常) → 幅/奥行/高さ/素材/カラーは上部の共通ブロックで表示済み -->
  10495. \t\t\t\t\t\t{% if ProductClass.SaleType.id == 1 %}
  10496. \t\t\t\t\t\t{% endif %}
  10497. \t\t\t\t\t\t<!-- 2: 施工見積(補助金・窓) 複数タイプ追加対応 (2026-05) -->
  10498. \t\t\t\t\t\t{% if ProductClass.SaleType.id == 2 %}
  10499. \t\t\t\t\t\t\t{# 2026-05 改修: ex-shop プラメイク方式に倣い、1 商品で
  10500. \t\t\t\t\t\t\t   複数の「窓タイプ」(subtype × 幅 × 高さ × ガラス × カラー × セット数)
  10501. \t\t\t\t\t\t\t   を追加できる UI に変更. 各タイプは内訳 JSON として 1 明細にまとめる. #}
  10502. \t\t\t\t\t\t\t{# ec-productRole__profile は標準テンプレで height:600px / overflow:auto
  10503. \t\t\t\t\t\t\t   が当たっており、複数タイプ追加カードが内部スクロールに押し込まれて
  10504. \t\t\t\t\t\t\t   見えない. sale_type=2 のときだけ縦方向に伸ばす. #}
  10505. \t\t\t\t\t\t\t<style>
  10506. \t\t\t\t\t\t\t\t.ec-productRole__profile {
  10507. \t\t\t\t\t\t\t\t\toverflow: visible !important;
  10508. \t\t\t\t\t\t\t\t\tmax-height: none !important;
  10509. \t\t\t\t\t\t\t\t\theight: auto !important;
  10510. \t\t\t\t\t\t\t\t}
  10511. \t\t\t\t\t\t\t</style>
  10512. \t\t\t\t\t\t\t{# 住宅区分 UI: 補助金単価が戸建 / 集合住宅で異なるためお客様に申告いただく. #}
  10513. \t\t\t\t\t\t\t{% set housing_default = getProduct_field(Product.id, '住宅区分')|default('戸建') %}
  10514. \t\t\t\t\t\t\t<div class=\"card mt-3 mb-3\">
  10515. \t\t\t\t\t\t\t  <div class=\"card-header\" style=\"background:#fff3cd;color:#333;\">
  10516. \t\t\t\t\t\t\t    <strong>お住まいの種別を選択</strong>
  10517. \t\t\t\t\t\t\t    <small class=\"ms-2 text-muted\">補助金単価が変わります</small>
  10518. \t\t\t\t\t\t\t  </div>
  10519. \t\t\t\t\t\t\t  <div class=\"card-body p-2\">
  10520. \t\t\t\t\t\t\t    <div class=\"opt-btn-group\" id=\"window-housing-type-group\">
  10521. \t\t\t\t\t\t\t      <label class=\"opt-btn\">
  10522. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"window_housing_type\" value=\"戸建\"
  10523. \t\t\t\t\t\t\t               {% if housing_default != '集合住宅' %}checked{% endif %}>
  10524. \t\t\t\t\t\t\t        戸建住宅<small class=\"d-block text-muted\">(延床240㎡以下の非住宅含む)</small>
  10525. \t\t\t\t\t\t\t      </label>
  10526. \t\t\t\t\t\t\t      <label class=\"opt-btn\">
  10527. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"window_housing_type\" value=\"集合住宅\"
  10528. \t\t\t\t\t\t\t               {% if housing_default == '集合住宅' %}checked{% endif %}>
  10529. \t\t\t\t\t\t\t        集合住宅<small class=\"d-block text-muted\">(低層・中高層/240㎡超の非住宅)</small>
  10530. \t\t\t\t\t\t\t      </label>
  10531. \t\t\t\t\t\t\t    </div>
  10532. \t\t\t\t\t\t\t  </div>
  10533. \t\t\t\t\t\t\t</div>
  10534. \t\t\t\t\t\t\t<div class=\"card mt-3 mb-3\">
  10535. \t\t\t\t\t\t\t  <div class=\"card-header\" style=\"background:#fff3cd;color:#333;\">
  10536. \t\t\t\t\t\t\t    <strong>窓タイプを選択(複数追加可・最大 20)</strong>
  10537. \t\t\t\t\t\t\t  </div>
  10538. \t\t\t\t\t\t\t  <div class=\"card-body p-2\">
  10539. \t\t\t\t\t\t\t    <div id=\"window-types-container\"><!-- 動的に窓タイプブロックが追加される --></div>
  10540. \t\t\t\t\t\t\t    <div class=\"text-center mt-2\">
  10541. \t\t\t\t\t\t\t      <button type=\"button\" id=\"btn-add-window-type\" class=\"btn btn-outline-primary btn-sm\" onclick=\"addWindowType();\">+ 窓タイプを追加</button>
  10542. \t\t\t\t\t\t\t      <div class=\"small text-muted mt-1\">最大 20 タイプまで追加できます</div>
  10543. \t\t\t\t\t\t\t    </div>
  10544. \t\t\t\t\t\t\t  </div>
  10545. \t\t\t\t\t\t\t</div>
  10546. \t\t\t\t\t\t\t{# 窓タイプブロックのテンプレート. __IDX__ を JS で連番に置換して clone する. #}
  10547. \t\t\t\t\t\t\t<template id=\"window-type-template\">
  10548. \t\t\t\t\t\t\t  <div class=\"window-type-block\" data-type-idx=\"__IDX__\" style=\"border:1px solid #ddd;border-radius:6px;padding:10px;margin-bottom:10px;background:#fafafa;\">
  10549. \t\t\t\t\t\t\t    <div class=\"d-flex justify-content-between align-items-center mb-2\">
  10550. \t\t\t\t\t\t\t      <strong>窓タイプ <span class=\"wt-num\">__IDX__</span></strong>
  10551. \t\t\t\t\t\t\t      <button type=\"button\" class=\"btn btn-sm btn-outline-danger btn-remove-window-type\" onclick=\"removeWindowType(this);\">× 削除</button>
  10552. \t\t\t\t\t\t\t    </div>
  10553. \t\t\t\t\t\t\t    {# 窓タイプ (subtype) #}
  10554. \t\t\t\t\t\t\t    {% if p_option1 and p_option1|length and p_option1|join != \"\" %}
  10555. \t\t\t\t\t\t\t    <div class=\"form-group mt-2 pb-2\" style=\"border-bottom:1px dashed rgba(0,0,0,.1)\">
  10556. \t\t\t\t\t\t\t      <div class=\"rp-section-label\">窓タイプ</div>
  10557. \t\t\t\t\t\t\t      <div class=\"opt-btn-group\">
  10558. \t\t\t\t\t\t\t        {% for v in p_option1 %}{% if v %}
  10559. \t\t\t\t\t\t\t          <label class=\"opt-btn\">
  10560. \t\t\t\t\t\t\t            <input type=\"radio\" name=\"wt_subtype___IDX__\" value=\"{{ v }}\" data-axis=\"subtype\" onchange=\"onWindowTypeAxisChange(this);\">
  10561. \t\t\t\t\t\t\t            {{ v }}
  10562. \t\t\t\t\t\t\t          </label>
  10563. \t\t\t\t\t\t\t        {% endif %}{% endfor %}
  10564. \t\t\t\t\t\t\t      </div>
  10565. \t\t\t\t\t\t\t    </div>
  10566. \t\t\t\t\t\t\t    {% endif %}
  10567. \t\t\t\t\t\t\t    {# 幅 (mm 直接入力) #}
  10568. \t\t\t\t\t\t\t    {% if p_w and p_w|length and p_w|join != \"\" %}
  10569. \t\t\t\t\t\t\t    <div class=\"form-group mt-2 pb-2\" style=\"border-bottom:1px dashed rgba(0,0,0,.1)\">
  10570. \t\t\t\t\t\t\t      <div class=\"rp-section-label\">幅</div>
  10571. \t\t\t\t\t\t\t      <div class=\"input-group\" style=\"max-width:240px;\">
  10572. \t\t\t\t\t\t\t        <input type=\"number\" name=\"wt_pw___IDX__\" class=\"form-control\" min=\"100\" step=\"10\"
  10573. \t\t\t\t\t\t\t               placeholder=\"例 1750\" data-axis=\"pw\" data-unit=\"mm\"
  10574. \t\t\t\t\t\t\t               oninput=\"onWindowTypeAxisChange(this);\">
  10575. \t\t\t\t\t\t\t        <span class=\"input-group-text\">mm</span>
  10576. \t\t\t\t\t\t\t      </div>
  10577. \t\t\t\t\t\t\t      <small class=\"text-muted\">商品の対応幅: 〜{{ (p_w|last)|default('') }}({{ p_w|length }} 段階の価格帯から自動選択)</small>
  10578. \t\t\t\t\t\t\t    </div>
  10579. \t\t\t\t\t\t\t    {% endif %}
  10580. \t\t\t\t\t\t\t    {# 高さ (mm 直接入力) #}
  10581. \t\t\t\t\t\t\t    {% if p_h and p_h|length and p_h|join != \"\" %}
  10582. \t\t\t\t\t\t\t    <div class=\"form-group mt-2 pb-2\" style=\"border-bottom:1px dashed rgba(0,0,0,.1)\">
  10583. \t\t\t\t\t\t\t      <div class=\"rp-section-label\">高さ</div>
  10584. \t\t\t\t\t\t\t      <div class=\"input-group\" style=\"max-width:240px;\">
  10585. \t\t\t\t\t\t\t        <input type=\"number\" name=\"wt_ph___IDX__\" class=\"form-control\" min=\"100\" step=\"10\"
  10586. \t\t\t\t\t\t\t               placeholder=\"例 1200\" data-axis=\"ph\" data-unit=\"mm\"
  10587. \t\t\t\t\t\t\t               oninput=\"onWindowTypeAxisChange(this);\">
  10588. \t\t\t\t\t\t\t        <span class=\"input-group-text\">mm</span>
  10589. \t\t\t\t\t\t\t      </div>
  10590. \t\t\t\t\t\t\t      <small class=\"text-muted\">商品の対応高さ: 〜{{ (p_h|last)|default('') }}({{ p_h|length }} 段階の価格帯から自動選択)</small>
  10591. \t\t\t\t\t\t\t    </div>
  10592. \t\t\t\t\t\t\t    {% endif %}
  10593. \t\t\t\t\t\t\t    {# ガラスタイプ #}
  10594. \t\t\t\t\t\t\t    {% if p_m and p_m|length and p_m|join != \"\" %}
  10595. \t\t\t\t\t\t\t    <div class=\"form-group mt-2 pb-2\" style=\"border-bottom:1px dashed rgba(0,0,0,.1)\">
  10596. \t\t\t\t\t\t\t      <div class=\"rp-section-label\">ガラスタイプ</div>
  10597. \t\t\t\t\t\t\t      <div class=\"opt-btn-group\">
  10598. \t\t\t\t\t\t\t        {% for v in p_m %}{% if v %}
  10599. \t\t\t\t\t\t\t          <label class=\"opt-btn\">
  10600. \t\t\t\t\t\t\t            <input type=\"radio\" name=\"wt_pm___IDX__\" value=\"{{ v }}\" data-axis=\"pm\" onchange=\"onWindowTypeAxisChange(this);\">
  10601. \t\t\t\t\t\t\t            {{ v }}
  10602. \t\t\t\t\t\t\t          </label>
  10603. \t\t\t\t\t\t\t        {% endif %}{% endfor %}
  10604. \t\t\t\t\t\t\t      </div>
  10605. \t\t\t\t\t\t\t      <small class=\"text-muted\">「<span style=\"color:#2e7d32;font-weight:bold;\">補助金対象</span>」が付いたガラスは、先進的窓リノベ補助金の対象です。</small>
  10606. \t\t\t\t\t\t\t    </div>
  10607. \t\t\t\t\t\t\t    {% endif %}
  10608. \t\t\t\t\t\t\t    {# 窓枠カラー #}
  10609. \t\t\t\t\t\t\t    {% if color and color|length %}
  10610. \t\t\t\t\t\t\t    <div class=\"form-group mt-2 pb-2\" style=\"border-bottom:1px dashed rgba(0,0,0,.1)\">
  10611. \t\t\t\t\t\t\t      <div class=\"rp-section-label\">窓枠カラー</div>
  10612. \t\t\t\t\t\t\t      <div class=\"opt-btn-group\">
  10613. \t\t\t\t\t\t\t        {% for cc in color %}{% if cc and cc['name'] %}
  10614. \t\t\t\t\t\t\t          {% set has_img = cc['img'] is defined and cc['img'] is not empty %}
  10615. \t\t\t\t\t\t\t          <label class=\"opt-btn{% if has_img %} opt-btn--with-image{% endif %}\">
  10616. \t\t\t\t\t\t\t            <input type=\"radio\" name=\"wt_pc___IDX__\" value=\"{{ cc['name'] }}\" data-axis=\"pc\" onchange=\"onWindowTypeAxisChange(this);\">
  10617. \t\t\t\t\t\t\t            {% if has_img %}
  10618. \t\t\t\t\t\t\t              <img src=\"{{ cc['img'] }}\" alt=\"{{ cc['name'] }}\" class=\"opt-btn__img\"
  10619. \t\t\t\t\t\t\t                   onerror=\"this.parentNode.classList.remove('opt-btn--with-image'); this.remove();\">
  10620. \t\t\t\t\t\t\t              <span class=\"opt-btn__name\">{{ cc['name'] }}</span>
  10621. \t\t\t\t\t\t\t            {% else %}
  10622. \t\t\t\t\t\t\t              {{ cc['name'] }}
  10623. \t\t\t\t\t\t\t            {% endif %}
  10624. \t\t\t\t\t\t\t          </label>
  10625. \t\t\t\t\t\t\t        {% endif %}{% endfor %}
  10626. \t\t\t\t\t\t\t      </div>
  10627. \t\t\t\t\t\t\t    </div>
  10628. \t\t\t\t\t\t\t    {% endif %}
  10629. \t\t\t\t\t\t\t    {# セット数 + タイプごとの補助金額表示 (補助金は task 2 で実計算) #}
  10630. \t\t\t\t\t\t\t    <div class=\"form-group row mt-2 align-items-center\">
  10631. \t\t\t\t\t\t\t      <label class=\"col-4 col-form-label\">セット数</label>
  10632. \t\t\t\t\t\t\t      <div class=\"col-4\">
  10633. \t\t\t\t\t\t\t        <div class=\"input-group\">
  10634. \t\t\t\t\t\t\t          <input type=\"number\" name=\"wt_setqty___IDX__\" class=\"form-control wt-input-setqty\" value=\"1\" min=\"1\" max=\"99\" data-axis=\"setqty\" onchange=\"onWindowTypeAxisChange(this);\">
  10635. \t\t\t\t\t\t\t          <span class=\"input-group-text\">セット</span>
  10636. \t\t\t\t\t\t\t        </div>
  10637. \t\t\t\t\t\t\t      </div>
  10638. \t\t\t\t\t\t\t      <div class=\"col-4 text-end\">
  10639. \t\t\t\t\t\t\t        <small class=\"text-muted\">補助金額<br><span class=\"wt-subsidy-amount\">―</span> 円</small>
  10640. \t\t\t\t\t\t\t      </div>
  10641. \t\t\t\t\t\t\t    </div>
  10642. \t\t\t\t\t\t\t  </div>
  10643. \t\t\t\t\t\t\t</template>
  10644. \t\t\t\t\t\t\t{# 複数タイプ管理 JS. addWindowType / removeWindowType / 再番号付け. #}
  10645. \t\t\t\t\t\t\t<script>
  10646. \t\t\t\t\t\t\t(function() {
  10647. \t\t\t\t\t\t\t\tvar MAX_WINDOW_TYPES = 20;
  10648. \t\t\t\t\t\t\t\tfunction addWindowType() {
  10649. \t\t\t\t\t\t\t\t\tvar container = document.getElementById('window-types-container');
  10650. \t\t\t\t\t\t\t\t\tif (!container) return;
  10651. \t\t\t\t\t\t\t\t\tvar existing = container.querySelectorAll('.window-type-block');
  10652. \t\t\t\t\t\t\t\t\tif (existing.length >= MAX_WINDOW_TYPES) return;
  10653. \t\t\t\t\t\t\t\t\tvar newIdx = existing.length + 1;
  10654. \t\t\t\t\t\t\t\t\tvar tpl = document.getElementById('window-type-template');
  10655. \t\t\t\t\t\t\t\t\tif (!tpl) return;
  10656. \t\t\t\t\t\t\t\t\t// <template> の innerHTML を取り出して __IDX__ を新規連番に置換し、要素化して append.
  10657. \t\t\t\t\t\t\t\t\tvar html = tpl.innerHTML.replace(/__IDX__/g, String(newIdx));
  10658. \t\t\t\t\t\t\t\t\tvar wrapper = document.createElement('div');
  10659. \t\t\t\t\t\t\t\t\twrapper.innerHTML = html.trim();
  10660. \t\t\t\t\t\t\t\t\tvar block = wrapper.firstChild;
  10661. \t\t\t\t\t\t\t\t\tcontainer.appendChild(block);
  10662. \t\t\t\t\t\t\t\t\tdecorateSubsidyGlass(block);
  10663. \t\t\t\t\t\t\t\t\tupdateRemoveButtonVisibility();
  10664. \t\t\t\t\t\t\t\t\tif (typeof recalcAll === 'function') recalcAll();
  10665. \t\t\t\t\t\t\t\t}
  10666. \t\t\t\t\t\t\t\t// 補助金対象ガラスの選択肢に「補助金対象」バッジ + 緑枠を付与する.
  10667. \t\t\t\t\t\t\t\t// 判定は calc script 側の window.glassYieldsSubsidy に委譲 (ロジック二重化を避ける)。
  10668. \t\t\t\t\t\t\t\tfunction decorateSubsidyGlass(block) {
  10669. \t\t\t\t\t\t\t\t\tif (!block || typeof window.glassYieldsSubsidy !== 'function') return;
  10670. \t\t\t\t\t\t\t\t\tvar radios = block.querySelectorAll('input[data-axis=\"pm\"]');
  10671. \t\t\t\t\t\t\t\t\tradios.forEach(function(inp) {
  10672. \t\t\t\t\t\t\t\t\t\tvar label = inp.closest('.opt-btn');
  10673. \t\t\t\t\t\t\t\t\t\tif (!label || label.querySelector('.opt-btn__subsidy-badge')) return;
  10674. \t\t\t\t\t\t\t\t\t\tif (window.glassYieldsSubsidy(inp.value)) {
  10675. \t\t\t\t\t\t\t\t\t\t\tlabel.classList.add('opt-btn--subsidy');
  10676. \t\t\t\t\t\t\t\t\t\t\tvar badge = document.createElement('span');
  10677. \t\t\t\t\t\t\t\t\t\t\tbadge.className = 'opt-btn__subsidy-badge';
  10678. \t\t\t\t\t\t\t\t\t\t\tbadge.textContent = '補助金対象';
  10679. \t\t\t\t\t\t\t\t\t\t\tlabel.appendChild(badge);
  10680. \t\t\t\t\t\t\t\t\t\t}
  10681. \t\t\t\t\t\t\t\t\t});
  10682. \t\t\t\t\t\t\t\t}
  10683. \t\t\t\t\t\t\t\tfunction removeWindowType(btn) {
  10684. \t\t\t\t\t\t\t\t\tvar block = btn.closest('.window-type-block');
  10685. \t\t\t\t\t\t\t\t\tif (!block) return;
  10686. \t\t\t\t\t\t\t\t\tblock.remove();
  10687. \t\t\t\t\t\t\t\t\treindexBlocks();
  10688. \t\t\t\t\t\t\t\t\tupdateRemoveButtonVisibility();
  10689. \t\t\t\t\t\t\t\t\tif (typeof recalcAll === 'function') recalcAll();
  10690. \t\t\t\t\t\t\t\t}
  10691. \t\t\t\t\t\t\t\tfunction updateRemoveButtonVisibility() {
  10692. \t\t\t\t\t\t\t\t\tvar blocks = document.querySelectorAll('#window-types-container .window-type-block');
  10693. \t\t\t\t\t\t\t\t\tblocks.forEach(function(b) {
  10694. \t\t\t\t\t\t\t\t\t\tvar btn = b.querySelector('.btn-remove-window-type');
  10695. \t\t\t\t\t\t\t\t\t\tif (btn) btn.style.display = blocks.length > 1 ? '' : 'none';
  10696. \t\t\t\t\t\t\t\t\t});
  10697. \t\t\t\t\t\t\t\t}
  10698. \t\t\t\t\t\t\t\tfunction reindexBlocks() {
  10699. \t\t\t\t\t\t\t\t\t// ブロック削除後に 1 から振り直し. input[name] の末尾 _N も書き換える.
  10700. \t\t\t\t\t\t\t\t\tvar blocks = document.querySelectorAll('#window-types-container .window-type-block');
  10701. \t\t\t\t\t\t\t\t\tblocks.forEach(function(b, i) {
  10702. \t\t\t\t\t\t\t\t\t\tvar n = i + 1;
  10703. \t\t\t\t\t\t\t\t\t\tb.setAttribute('data-type-idx', String(n));
  10704. \t\t\t\t\t\t\t\t\t\tvar numSpan = b.querySelector('.wt-num');
  10705. \t\t\t\t\t\t\t\t\t\tif (numSpan) numSpan.textContent = String(n);
  10706. \t\t\t\t\t\t\t\t\t\tb.querySelectorAll('input[name]').forEach(function(inp) {
  10707. \t\t\t\t\t\t\t\t\t\t\tinp.name = inp.name.replace(/_\\d+\$/, '_' + n);
  10708. \t\t\t\t\t\t\t\t\t\t});
  10709. \t\t\t\t\t\t\t\t\t});
  10710. \t\t\t\t\t\t\t\t}
  10711. \t\t\t\t\t\t\t\t// 軸変更イベント. recalcAll が定義されていれば再計算 (task 2 で実装).
  10712. \t\t\t\t\t\t\t\twindow.onWindowTypeAxisChange = function() {
  10713. \t\t\t\t\t\t\t\t\tif (typeof recalcAll === 'function') recalcAll();
  10714. \t\t\t\t\t\t\t\t};
  10715. \t\t\t\t\t\t\t\twindow.addWindowType = addWindowType;
  10716. \t\t\t\t\t\t\t\twindow.removeWindowType = removeWindowType;
  10717. \t\t\t\t\t\t\t\t// 隠し radio(opacity:0/pointer-events:none) を label で包む opt-btn は iOS で初回タップの
  10718. \t\t\t\t\t\t\t\t// change が不発になりやすい。窓タイプ/住宅区分は label に onclick が無く change 依存だった
  10719. \t\t\t\t\t\t\t\t// ため「2回タッチ/選択できない」が発生。click は確実に発火するので委譲 click で選択状態・
  10720. \t\t\t\t\t\t\t\t// is-selected・再計算を行う(JSで複製される窓タイプにも委譲で対応)。
  10721. \t\t\t\t\t\t\t\tdocument.addEventListener('click', function(ev) {
  10722. \t\t\t\t\t\t\t\t\tif (!ev.target || !ev.target.closest) return;
  10723. \t\t\t\t\t\t\t\t\tvar label = ev.target.closest('.opt-btn');
  10724. \t\t\t\t\t\t\t\t\tif (!label) return;
  10725. \t\t\t\t\t\t\t\t\tif (!label.closest('#window-types-container') && !label.closest('#window-housing-type-group')) return;
  10726. \t\t\t\t\t\t\t\t\tvar input = label.querySelector('input[type=\"radio\"]');
  10727. \t\t\t\t\t\t\t\t\tif (!input || input.disabled) return;
  10728. \t\t\t\t\t\t\t\t\tinput.checked = true;
  10729. \t\t\t\t\t\t\t\t\tvar nm = input.getAttribute('name');
  10730. \t\t\t\t\t\t\t\t\tif (nm) {
  10731. \t\t\t\t\t\t\t\t\t\tdocument.querySelectorAll('input[name=\"' + nm + '\"]').forEach(function(i) {
  10732. \t\t\t\t\t\t\t\t\t\t\tvar l = i.closest('.opt-btn');
  10733. \t\t\t\t\t\t\t\t\t\t\tif (l) l.classList.toggle('is-selected', i.checked);
  10734. \t\t\t\t\t\t\t\t\t\t});
  10735. \t\t\t\t\t\t\t\t\t}
  10736. \t\t\t\t\t\t\t\t\tif (typeof recalcAll === 'function') recalcAll();
  10737. \t\t\t\t\t\t\t\t});
  10738. \t\t\t\t\t\t\t\t// 初期表示で 1 ブロック追加 + 住宅区分ラジオの change で再計算.
  10739. \t\t\t\t\t\t\t\tdocument.addEventListener('DOMContentLoaded', function() {
  10740. \t\t\t\t\t\t\t\t\tif (document.querySelector('#window-types-container')) {
  10741. \t\t\t\t\t\t\t\t\t\taddWindowType();
  10742. \t\t\t\t\t\t\t\t\t}
  10743. \t\t\t\t\t\t\t\t\tvar housingInputs = document.querySelectorAll('input[name=\"window_housing_type\"]');
  10744. \t\t\t\t\t\t\t\t\tvar syncHousingSelectedClass = function() {
  10745. \t\t\t\t\t\t\t\t\t\thousingInputs.forEach(function(el) {
  10746. \t\t\t\t\t\t\t\t\t\t\tvar lbl = el.closest('.opt-btn');
  10747. \t\t\t\t\t\t\t\t\t\t\tif (!lbl) return;
  10748. \t\t\t\t\t\t\t\t\t\t\tif (el.checked) lbl.classList.add('is-selected');
  10749. \t\t\t\t\t\t\t\t\t\t\telse            lbl.classList.remove('is-selected');
  10750. \t\t\t\t\t\t\t\t\t\t});
  10751. \t\t\t\t\t\t\t\t\t};
  10752. \t\t\t\t\t\t\t\t\tsyncHousingSelectedClass();
  10753. \t\t\t\t\t\t\t\t\thousingInputs.forEach(function(el) {
  10754. \t\t\t\t\t\t\t\t\t\tel.addEventListener('change', function() {
  10755. \t\t\t\t\t\t\t\t\t\t\tsyncHousingSelectedClass();
  10756. \t\t\t\t\t\t\t\t\t\t\tif (typeof recalcAll === 'function') recalcAll();
  10757. \t\t\t\t\t\t\t\t\t\t});
  10758. \t\t\t\t\t\t\t\t\t});
  10759. \t\t\t\t\t\t\t\t});
  10760. \t\t\t\t\t\t\t})();
  10761. \t\t\t\t\t\t\t</script>
  10762. \t\t\t\t\t\t{% endif %}
  10763. \t\t\t\t\t\t<!-- 3: 施工見積(物置・ゴミステーション) -->
  10764. \t\t\t\t\t\t{% if ProductClass.SaleType.id == 3 %}
  10765. \t\t\t\t\t\t\t{# 幅・奥行き・高さ(p_w/p_d/p_h からボタン型ラジオ生成) #}
  10766. \t\t\t\t\t\t\t{% if p_w and p_w|length and p_w|join != \"\" %}
  10767. \t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10768. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">幅{% if mitsumori_json and mitsumori_json.pw %}: <span>{{ mitsumori_json.pw }}</span>{% endif %}</div>
  10769. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  10770. \t\t\t\t\t\t\t    {% set idx = 0 %}
  10771. \t\t\t\t\t\t\t    {% for pw_val in p_w %}{% if pw_val %}{% set idx = idx + 1 %}
  10772. \t\t\t\t\t\t\t      <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.pw == pw_val) or p_w|length == 1 %} is-selected{% endif %}\"
  10773. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('pw','pw3_{{ idx }}');\">
  10774. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"pw\" id=\"pw3_{{ idx }}\" value=\"{{ pw_val }}\"
  10775. \t\t\t\t\t\t\t               {% if (mitsumori_json and mitsumori_json.pw == pw_val) or p_w|length == 1 %}checked{% endif %}>
  10776. \t\t\t\t\t\t\t        {{ pw_val }}
  10777. \t\t\t\t\t\t\t      </label>
  10778. \t\t\t\t\t\t\t    {% endif %}{% endfor %}
  10779. \t\t\t\t\t\t\t  </div>
  10780. \t\t\t\t\t\t\t</div>
  10781. \t\t\t\t\t\t\t{% endif %}
  10782. \t\t\t\t\t\t\t{% if p_d and p_d|length and p_d|join != \"\" %}
  10783. \t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10784. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">奥行き{% if mitsumori_json and mitsumori_json.pd %}: <span>{{ mitsumori_json.pd }}</span>{% endif %}</div>
  10785. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  10786. \t\t\t\t\t\t\t    {% set idx = 0 %}
  10787. \t\t\t\t\t\t\t    {% for pd_val in p_d %}{% if pd_val %}{% set idx = idx + 1 %}
  10788. \t\t\t\t\t\t\t      <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.pd == pd_val) or p_d|length == 1 %} is-selected{% endif %}\"
  10789. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('pd','pd3_{{ idx }}');\">
  10790. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"pd\" id=\"pd3_{{ idx }}\" value=\"{{ pd_val }}\"
  10791. \t\t\t\t\t\t\t               {% if (mitsumori_json and mitsumori_json.pd == pd_val) or p_d|length == 1 %}checked{% endif %}>
  10792. \t\t\t\t\t\t\t        {{ pd_val }}
  10793. \t\t\t\t\t\t\t      </label>
  10794. \t\t\t\t\t\t\t    {% endif %}{% endfor %}
  10795. \t\t\t\t\t\t\t  </div>
  10796. \t\t\t\t\t\t\t</div>
  10797. \t\t\t\t\t\t\t{% endif %}
  10798. \t\t\t\t\t\t\t{% if p_h and p_h|length and p_h|join != \"\" %}
  10799. \t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10800. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">高さ{% if mitsumori_json and mitsumori_json.ph %}: <span>{{ mitsumori_json.ph }}</span>{% endif %}</div>
  10801. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  10802. \t\t\t\t\t\t\t    {% set idx = 0 %}
  10803. \t\t\t\t\t\t\t    {% for ph_val in p_h %}{% if ph_val %}{% set idx = idx + 1 %}
  10804. \t\t\t\t\t\t\t      <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.ph == ph_val) or p_h|length == 1 %} is-selected{% endif %}\"
  10805. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('ph','ph3_{{ idx }}');\">
  10806. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"ph\" id=\"ph3_{{ idx }}\" value=\"{{ ph_val }}\"
  10807. \t\t\t\t\t\t\t               {% if (mitsumori_json and mitsumori_json.ph == ph_val) or p_h|length == 1 %}checked{% endif %}>
  10808. \t\t\t\t\t\t\t        {{ ph_val }}
  10809. \t\t\t\t\t\t\t      </label>
  10810. \t\t\t\t\t\t\t    {% endif %}{% endfor %}
  10811. \t\t\t\t\t\t\t  </div>
  10812. \t\t\t\t\t\t\t</div>
  10813. \t\t\t\t\t\t\t{% endif %}
  10814. \t\t\t\t\t\t\t{# 棚タイプ(p_m データから選択肢を生成) #}
  10815. \t\t\t\t\t\t\t{% if p_m and p_m|length and p_m|join != \"\" %}
  10816. \t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10817. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">棚タイプ <small class=\"text-muted\">(間仕切り仕様)</small>{% if mitsumori_json and mitsumori_json.pm %}: <span>{{ mitsumori_json.pm }}</span>{% endif %}</div>
  10818. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  10819. \t\t\t\t\t\t\t    {% set idx = 0 %}
  10820. \t\t\t\t\t\t\t    {% for pm_val in p_m %}{% if pm_val %}{% set idx = idx + 1 %}
  10821. \t\t\t\t\t\t\t      <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.pm == pm_val) or p_m|length == 1 %} is-selected{% endif %}\"
  10822. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('pm','pm3_{{ idx }}');\">
  10823. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"pm\" id=\"pm3_{{ idx }}\" value=\"{{ pm_val }}\"
  10824. \t\t\t\t\t\t\t               {% if (mitsumori_json and mitsumori_json.pm == pm_val) or p_m|length == 1 %}checked{% endif %}>
  10825. \t\t\t\t\t\t\t        {{ pm_val }}
  10826. \t\t\t\t\t\t\t      </label>
  10827. \t\t\t\t\t\t\t    {% endif %}{% endfor %}
  10828. \t\t\t\t\t\t\t  </div>
  10829. \t\t\t\t\t\t\t</div>
  10830. \t\t\t\t\t\t\t{% endif %}
  10831. \t\t\t\t\t\t\t{# option1 (mo の 棚タイプ 等、p_option1 データから選択肢を生成) #}
  10832. \t\t\t\t\t\t\t{% if p_option1 and p_option1|length and p_option1|join != \"\" %}
  10833. \t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10834. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">{{ option1_label }}{% if mitsumori_json and mitsumori_json.option1 is defined and mitsumori_json.option1 %}: <span>{{ mitsumori_json.option1 }}</span>{% endif %}</div>
  10835. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  10836. \t\t\t\t\t\t\t    {% set idx = 0 %}
  10837. \t\t\t\t\t\t\t    {% for opt1_val in p_option1 %}{% if opt1_val %}{% set idx = idx + 1 %}
  10838. \t\t\t\t\t\t\t      <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.option1 is defined and mitsumori_json.option1 == opt1_val) or p_option1|length == 1 %} is-selected{% endif %}\"
  10839. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('option1','option1_3_{{ idx }}');\">
  10840. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"option1\" id=\"option1_3_{{ idx }}\" value=\"{{ opt1_val }}\"
  10841. \t\t\t\t\t\t\t               {% if (mitsumori_json and mitsumori_json.option1 is defined and mitsumori_json.option1 == opt1_val) or p_option1|length == 1 %}checked{% endif %}>
  10842. \t\t\t\t\t\t\t        {{ opt1_val }}
  10843. \t\t\t\t\t\t\t      </label>
  10844. \t\t\t\t\t\t\t    {% endif %}{% endfor %}
  10845. \t\t\t\t\t\t\t  </div>
  10846. \t\t\t\t\t\t\t</div>
  10847. \t\t\t\t\t\t\t{% endif %}
  10848. \t\t\t\t\t\t\t{# カラー(共通の color データ使用) #}
  10849. \t\t\t\t\t\t\t{% if color and color|length %}
  10850. \t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10851. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">カラー{% if mitsumori_json and mitsumori_json.pc %}: <span>{{ mitsumori_json.pc }}</span>{% endif %}</div>
  10852. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  10853. \t\t\t\t\t\t\t    {% set idx = 0 %}
  10854. \t\t\t\t\t\t\t    {% for cc in color %}{% if cc and cc['name'] %}{% set idx = idx + 1 %}
  10855. \t\t\t\t\t\t\t      <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.pc == cc['name']) or color|length == 1 %} is-selected{% endif %}\"
  10856. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('pc','cc3_{{ idx }}');\">
  10857. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"color3\" id=\"cc3_{{ idx }}\" value=\"{{ cc['name'] }}\"
  10858. \t\t\t\t\t\t\t               {% if (mitsumori_json and mitsumori_json.pc == cc['name']) or color|length == 1 %}checked{% endif %}>
  10859. \t\t\t\t\t\t\t        {{ cc['name'] }}
  10860. \t\t\t\t\t\t\t      </label>
  10861. \t\t\t\t\t\t\t    {% endif %}{% endfor %}
  10862. \t\t\t\t\t\t\t  </div>
  10863. \t\t\t\t\t\t\t</div>
  10864. \t\t\t\t\t\t\t{% endif %}
  10865. \t\t\t\t\t\t\t{# 台数 #}
  10866. \t\t\t\t\t\t\t<div class=\"form-group row mt-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10867. \t\t\t\t\t\t\t  <label class=\"col-4 col-form-label\">台数</label>
  10868. \t\t\t\t\t\t\t  <div class=\"col-4\">
  10869. \t\t\t\t\t\t\t    <div class=\"input-group mb-3\">
  10870. \t\t\t\t\t\t\t      <input type=\"number\" name=\"daisu\" id=\"daisu\" class=\"form-control\" value=\"{{ mitsumori_json.daisu|default('1') }}\" min=\"1\" max=\"10\" onchange=\"mitsumori_simulation('daisu','daisu');\">
  10871. \t\t\t\t\t\t\t      <span class=\"input-group-text\">台</span>
  10872. \t\t\t\t\t\t\t    </div>
  10873. \t\t\t\t\t\t\t  </div>
  10874. \t\t\t\t\t\t\t  <div class=\"col-4\">
  10875. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-info\" onclick=\"daisu(+1);\">+</button>
  10876. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-danger\" onclick=\"daisu(-1);\">ー</button>
  10877. \t\t\t\t\t\t\t  </div>
  10878. \t\t\t\t\t\t\t</div>
  10879. \t\t\t\t\t\t{% endif %}
  10880. \t\t\t\t\t\t<!-- 4: 施工見積(フェンス・組み立て式) -->
  10881. \t\t\t\t\t\t{% if ProductClass.SaleType.id == 4 %}
  10882. \t\t\t\t\t\t\t{# 枚数 #}
  10883. \t\t\t\t\t\t\t<div class=\"form-group row mt-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10884. \t\t\t\t\t\t\t  <label class=\"col-4 col-form-label\">枚数</label>
  10885. \t\t\t\t\t\t\t  <div class=\"col-4 mb-3\">
  10886. \t\t\t\t\t\t\t    <div class=\"input-group\">
  10887. \t\t\t\t\t\t\t      <input type=\"number\" name=\"maisu\" id=\"maisu\" class=\"form-control\" value=\"{{ mitsumori_json.maisu|default('3') }}\" min=\"3\" max=\"20\" onchange=\"if(parseInt(this.value)<3)this.value=3; mitsumori_simulation('maisu','maisu');\">
  10888. \t\t\t\t\t\t\t      <span class=\"input-group-text\">枚</span>
  10889. \t\t\t\t\t\t\t    </div>
  10890. \t\t\t\t\t\t\t  </div>
  10891. \t\t\t\t\t\t\t  <div class=\"col-4\">
  10892. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-info\" onclick=\"maisu(+1);\">+</button>
  10893. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-danger\" onclick=\"maisu(-1);\">ー</button>
  10894. \t\t\t\t\t\t\t  </div>
  10895. \t\t\t\t\t\t\t</div>
  10896. \t\t\t\t\t\t{% endif %}
  10897. \t\t\t\t\t\t<!-- 5: 施工見積(ウッドデッキ・タイルデッキ) -->
  10898. \t\t\t\t\t\t{% if ProductClass.SaleType.id == 5 %}
  10899. \t\t\t\t\t\t\t{# ステップの有無 #}
  10900. \t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10901. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">ステップ</div>
  10902. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  10903. \t\t\t\t\t\t\t    {% set step_yes_checked = (mitsumori_json and mitsumori_json.deck_step is defined and mitsumori_json.deck_step == '必要') %}
  10904. \t\t\t\t\t\t\t    {% set step_no_checked = (not mitsumori_json or mitsumori_json.deck_step is not defined or mitsumori_json.deck_step == '不要' or not mitsumori_json.deck_step) %}
  10905. \t\t\t\t\t\t\t    <label class=\"opt-btn{% if step_yes_checked %} is-selected{% endif %}\"
  10906. \t\t\t\t\t\t\t           onclick=\"mitsumori_simulation('op0','deck_step_yes');\">
  10907. \t\t\t\t\t\t\t      <input type=\"radio\" name=\"deck_step\" id=\"deck_step_yes\" value=\"必要\"
  10908. \t\t\t\t\t\t\t             {% if step_yes_checked %}checked{% endif %}>
  10909. \t\t\t\t\t\t\t      必要
  10910. \t\t\t\t\t\t\t    </label>
  10911. \t\t\t\t\t\t\t    <label class=\"opt-btn{% if step_no_checked %} is-selected{% endif %}\"
  10912. \t\t\t\t\t\t\t           onclick=\"mitsumori_simulation('op0','deck_step_no');\">
  10913. \t\t\t\t\t\t\t      <input type=\"radio\" name=\"deck_step\" id=\"deck_step_no\" value=\"不要\"
  10914. \t\t\t\t\t\t\t             {% if step_no_checked %}checked{% endif %}>
  10915. \t\t\t\t\t\t\t      不要
  10916. \t\t\t\t\t\t\t    </label>
  10917. \t\t\t\t\t\t\t  </div>
  10918. \t\t\t\t\t\t\t  <div class=\"opt-survey-note-wd-step\" style=\"font-size:12px;color:#c00;margin-top:6px;{% if not step_yes_checked %}display:none;{% endif %}\">
  10919. \t\t\t\t\t\t\t    ※ 現場調査後に正式お見積もりさせていただきます。
  10920. \t\t\t\t\t\t\t  </div>
  10921. \t\t\t\t\t\t\t</div>
  10922. \t\t\t\t\t\t\t{# ウッドデッキフェンスの有無 #}
  10923. \t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10924. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">デッキフェンス</div>
  10925. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  10926. \t\t\t\t\t\t\t    {% set fence_yes_checked = (mitsumori_json and mitsumori_json.deck_fence is defined and mitsumori_json.deck_fence == '必要') %}
  10927. \t\t\t\t\t\t\t    {% set fence_no_checked = (not mitsumori_json or mitsumori_json.deck_fence is not defined or mitsumori_json.deck_fence == '不要' or not mitsumori_json.deck_fence) %}
  10928. \t\t\t\t\t\t\t    <label class=\"opt-btn{% if fence_yes_checked %} is-selected{% endif %}\"
  10929. \t\t\t\t\t\t\t           onclick=\"mitsumori_simulation('op1','deck_fence_yes');\">
  10930. \t\t\t\t\t\t\t      <input type=\"radio\" name=\"deck_fence\" id=\"deck_fence_yes\" value=\"必要\"
  10931. \t\t\t\t\t\t\t             {% if fence_yes_checked %}checked{% endif %}>
  10932. \t\t\t\t\t\t\t      必要
  10933. \t\t\t\t\t\t\t    </label>
  10934. \t\t\t\t\t\t\t    <label class=\"opt-btn{% if fence_no_checked %} is-selected{% endif %}\"
  10935. \t\t\t\t\t\t\t           onclick=\"mitsumori_simulation('op1','deck_fence_no');\">
  10936. \t\t\t\t\t\t\t      <input type=\"radio\" name=\"deck_fence\" id=\"deck_fence_no\" value=\"不要\"
  10937. \t\t\t\t\t\t\t             {% if fence_no_checked %}checked{% endif %}>
  10938. \t\t\t\t\t\t\t      不要
  10939. \t\t\t\t\t\t\t    </label>
  10940. \t\t\t\t\t\t\t  </div>
  10941. \t\t\t\t\t\t\t  <div class=\"opt-survey-note-wd-fence\" style=\"font-size:12px;color:#c00;margin-top:6px;{% if not fence_yes_checked %}display:none;{% endif %}\">
  10942. \t\t\t\t\t\t\t    ※ 現場調査後に正式お見積もりさせていただきます。
  10943. \t\t\t\t\t\t\t  </div>
  10944. \t\t\t\t\t\t\t</div>
  10945. \t\t\t\t\t\t{% endif %}
  10946. \t\t\t\t\t\t<!-- 6: 施工見積(芝生・枚数・数量買い) -->
  10947. \t\t\t\t\t\t{% if ProductClass.SaleType.id == 6 %}
  10948. \t\t\t\t\t\t\t{# 規格(p_m データ → 素材から抽出) #}
  10949. \t\t\t\t\t\t\t{% if p_m and p_m|length and p_m|join != \"\" %}
  10950. \t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10951. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">規格{% if mitsumori_json and mitsumori_json.pm %}: <span>{{ mitsumori_json.pm }}</span>{% endif %}</div>
  10952. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  10953. \t\t\t\t\t\t\t    {% set idx = 0 %}
  10954. \t\t\t\t\t\t\t    {% for pm_val in p_m %}{% if pm_val %}{% set idx = idx + 1 %}
  10955. \t\t\t\t\t\t\t      <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.pm == pm_val) or p_m|length == 1 %} is-selected{% endif %}\"
  10956. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('pm','pm6_{{ idx }}');\">
  10957. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"pm\" id=\"pm6_{{ idx }}\" value=\"{{ pm_val }}\"
  10958. \t\t\t\t\t\t\t               {% if (mitsumori_json and mitsumori_json.pm == pm_val) or p_m|length == 1 %}checked{% endif %}>
  10959. \t\t\t\t\t\t\t        {{ pm_val }}
  10960. \t\t\t\t\t\t\t      </label>
  10961. \t\t\t\t\t\t\t    {% endif %}{% endfor %}
  10962. \t\t\t\t\t\t\t  </div>
  10963. \t\t\t\t\t\t\t</div>
  10964. \t\t\t\t\t\t\t{% endif %}
  10965. \t\t\t\t\t\t\t{# 芝の幅(p_w = ロール幅。free_area の w。例 100cm/200cm = 1m/2m 幅。
  10966. \t\t\t\t\t\t\t   h はロール長(例 1000cm=10m)で固定のため UI には出さない)。 #}
  10967. \t\t\t\t\t\t\t{% if p_w and p_w|length and p_w|join != \"\" %}
  10968. \t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10969. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">芝の幅{% if mitsumori_json and mitsumori_json.pw %}: <span>{{ mitsumori_json.pw }}</span>{% endif %}</div>
  10970. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  10971. \t\t\t\t\t\t\t    {% set idx = 0 %}
  10972. \t\t\t\t\t\t\t    {% for pw_val in p_w %}{% if pw_val %}{% set idx = idx + 1 %}
  10973. \t\t\t\t\t\t\t      <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.pw == pw_val) or p_w|length == 1 %} is-selected{% endif %}\"
  10974. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('pw','pw6_{{ idx }}');\">
  10975. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"pw\" id=\"pw6_{{ idx }}\" value=\"{{ pw_val }}\"
  10976. \t\t\t\t\t\t\t               {% if (mitsumori_json and mitsumori_json.pw == pw_val) or p_w|length == 1 %}checked{% endif %}>
  10977. \t\t\t\t\t\t\t        {{ pw_val }}
  10978. \t\t\t\t\t\t\t      </label>
  10979. \t\t\t\t\t\t\t    {% endif %}{% endfor %}
  10980. \t\t\t\t\t\t\t  </div>
  10981. \t\t\t\t\t\t\t</div>
  10982. \t\t\t\t\t\t\t{% endif %}
  10983. \t\t\t\t\t\t\t{# 1ロールの長さ表記(顧客要望 #10)。h はロール長 (例 1000cm=10m) で固定のため選択ではなく表示のみ。 #}
  10984. \t\t\t\t\t\t\t{% set _roll_h = (p_h is defined and p_h|length) ? (p_h|first) : '' %}
  10985. \t\t\t\t\t\t\t{% if _roll_h %}
  10986. \t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10987. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">1ロールの長さ:<span style=\"font-weight:bold;\">{% if 'cm' in _roll_h %}{{ (_roll_h|replace({'cm':'', ',':''})|trim) / 100 }}m{% else %}{{ _roll_h }}{% endif %}</span></div>
  10988. \t\t\t\t\t\t\t</div>
  10989. \t\t\t\t\t\t\t{% endif %}
  10990. \t\t\t\t\t\t\t{# 施工サイズ(縦 × 横、m 入力)→ 必要枚数を自動算出して表示.
  10991. \t\t\t\t\t\t\t   面積=縦×横 を #area に流し込み、case 6 の qty=ceil(area/ロール面積) を流用. #}
  10992. \t\t\t\t\t\t\t<div class=\"form-group row mt-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10993. \t\t\t\t\t\t\t  <label class=\"col-4 col-form-label\">施工サイズ</label>
  10994. \t\t\t\t\t\t\t  <div class=\"col-8\">
  10995. \t\t\t\t\t\t\t    <div class=\"input-group\">
  10996. \t\t\t\t\t\t\t      <input type=\"number\" name=\"tf_len\" id=\"tf_len\"
  10997. \t\t\t\t\t\t\t        class=\"form-control\"
  10998. \t\t\t\t\t\t\t        value=\"{{ mitsumori_json.tf_len|default('') }}\"
  10999. \t\t\t\t\t\t\t        placeholder=\"縦\" min=\"0.1\" step=\"0.1\"
  11000. \t\t\t\t\t\t\t        onchange=\"mitsumori_simulation('tf_len','tf_len');\">
  11001. \t\t\t\t\t\t\t      <span class=\"input-group-text\">m&nbsp;×</span>
  11002. \t\t\t\t\t\t\t      <input type=\"number\" name=\"tf_wid\" id=\"tf_wid\"
  11003. \t\t\t\t\t\t\t        class=\"form-control\"
  11004. \t\t\t\t\t\t\t        value=\"{{ mitsumori_json.tf_wid|default('') }}\"
  11005. \t\t\t\t\t\t\t        placeholder=\"横\" min=\"0.1\" step=\"0.1\"
  11006. \t\t\t\t\t\t\t        onchange=\"mitsumori_simulation('tf_wid','tf_wid');\">
  11007. \t\t\t\t\t\t\t      <span class=\"input-group-text\">m</span>
  11008. \t\t\t\t\t\t\t    </div>
  11009. \t\t\t\t\t\t\t    {# area は内部計算用に保持(縦×横を JS で書き込む) #}
  11010. \t\t\t\t\t\t\t    <input type=\"hidden\" name=\"area\" id=\"area\" value=\"{{ mitsumori_json.area|default('') }}\">
  11011. \t\t\t\t\t\t\t    {# 必要枚数は直接入力も可能。施工サイズ入力時は自動算出して上書きする。
  11012. \t\t\t\t\t\t\t       施工サイズ未入力でも、ここで枚数だけ指定してカートに入れられる。 #}
  11013. \t\t\t\t\t\t\t    <div style=\"margin-top:10px;display:inline-block;background:#fff3cd;border:1px solid #ffe69c;border-radius:6px;padding:8px 14px;font-size:16px;color:#c00;font-weight:bold;\">
  11014. \t\t\t\t\t\t\t      必要枚数:<input type=\"number\" name=\"tf_qty\" id=\"tf_qty\"
  11015. \t\t\t\t\t\t\t        value=\"{{ mitsumori_json.tf_qty|default('1') }}\" min=\"1\" step=\"1\"
  11016. \t\t\t\t\t\t\t        style=\"width:80px;font-size:22px;font-weight:bold;color:#c00;text-align:right;border:1px solid #ffe69c;border-radius:4px;padding:2px 6px;\"
  11017. \t\t\t\t\t\t\t        onchange=\"mitsumori_simulation('tf_qty','tf_qty');\"> 枚
  11018. \t\t\t\t\t\t\t    </div>
  11019. \t\t\t\t\t\t\t    <div style=\"margin-top:6px;font-size:12px;color:#666;\">※ 施工サイズを入力すると必要枚数を自動計算します。サイズが分からない場合は枚数を直接ご指定ください。</div>
  11020. \t\t\t\t\t\t\t  </div>
  11021. \t\t\t\t\t\t\t</div>
  11022. \t\t\t\t\t\t{% endif %}
  11023. \t\t\t\t\t\t<!-- 7: 施工見積(数量買い・基本工事費固定) -->
  11024. \t\t\t\t\t\t{% if ProductClass.SaleType.id == 7 %}
  11025. \t\t\t\t\t\t\t{# 個数(物置の daisu と同形式、単位は「個」) #}
  11026. \t\t\t\t\t\t\t<div class=\"form-group row mt-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  11027. \t\t\t\t\t\t\t  <label class=\"col-4 col-form-label\">個数</label>
  11028. \t\t\t\t\t\t\t  <div class=\"col-4\">
  11029. \t\t\t\t\t\t\t    <div class=\"input-group mb-3\">
  11030. \t\t\t\t\t\t\t      <input type=\"number\" name=\"suuryou\" id=\"suuryou\" class=\"form-control\"
  11031. \t\t\t\t\t\t\t        value=\"{{ mitsumori_json.suuryou|default('1') }}\" min=\"1\" max=\"100\"
  11032. \t\t\t\t\t\t\t        onchange=\"mitsumori_simulation('suuryou','suuryou');\">
  11033. \t\t\t\t\t\t\t      <span class=\"input-group-text\">個</span>
  11034. \t\t\t\t\t\t\t    </div>
  11035. \t\t\t\t\t\t\t  </div>
  11036. \t\t\t\t\t\t\t  <div class=\"col-4\">
  11037. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-info\" onclick=\"suuryou(+1);\">+</button>
  11038. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-danger\" onclick=\"suuryou(-1);\">ー</button>
  11039. \t\t\t\t\t\t\t  </div>
  11040. \t\t\t\t\t\t\t</div>
  11041. \t\t\t\t\t\t{% endif %}
  11042. \t\t\t\t\t\t<!-- 9: 商品のみ購入 -->
  11043. \t\t\t\t\t\t{% if ProductClass.SaleType.id == 9 %}
  11044. \t\t\t\t\t\t\t<div class=\"form-group row mt-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  11045. \t\t\t\t\t\t\t  <label class=\"col-4 col-form-label\">数量</label>
  11046. \t\t\t\t\t\t\t  <div class=\"col-4\">
  11047. \t\t\t\t\t\t\t    <div class=\"input-group mb-3\">
  11048. \t\t\t\t\t\t\t      <input type=\"number\" name=\"quantity_only\" id=\"quantity_only\" class=\"form-control\" value=\"1\" min=\"1\" onchange=\"\$('#quantity').val(this.value);\">
  11049. \t\t\t\t\t\t\t      <span class=\"input-group-text\">個</span>
  11050. \t\t\t\t\t\t\t    </div>
  11051. \t\t\t\t\t\t\t  </div>
  11052. \t\t\t\t\t\t\t  <div class=\"col-4\">
  11053. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-info\" onclick=\"quantityOnly(+1);\">+</button>
  11054. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-danger\" onclick=\"quantityOnly(-1);\">ー</button>
  11055. \t\t\t\t\t\t\t  </div>
  11056. \t\t\t\t\t\t\t</div>
  11057. \t\t\t\t\t\t{% endif %}
  11058. \t\t\t\t\t    <div class=\"row\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\"><label class=\"col-12 col-form-label\">取り付け工事のご希望に関してお答えください。</label></div>
  11059. \t\t\t\t\t\t{# gs (ゴミステーション, category id=27) では「撤去対応」「残土・ガラ処理」は ex-shop に存在しないため非表示
  11060. \t\t\t\t\t\t   cg (カーゲート, category id=9) では「残土・ガラ処理」分は撤去金額側に内包済みのため非表示
  11061. \t\t\t\t\t\t   (撤去オプション自体は残す) #}
  11062. \t\t\t\t\t\t{% set is_gs = false %}
  11063. \t\t\t\t\t\t{% set is_cg = false %}
  11064. \t\t\t\t\t\t{% if Product.ProductCategories is not empty %}
  11065. \t\t\t\t\t\t\t{% for ProductCategory in Product.ProductCategories %}
  11066. \t\t\t\t\t\t\t\t{% if ProductCategory.category_id == 27 %}{% set is_gs = true %}{% endif %}
  11067. \t\t\t\t\t\t\t\t{% if ProductCategory.category_id == 9 %}{% set is_cg = true %}{% endif %}
  11068. \t\t\t\t\t\t\t{% endfor %}
  11069. \t\t\t\t\t\t{% endif %}
  11070. \t\t\t\t\t\t{% for i in 0..10 %}
  11071. \t\t\t\t\t\t\t{% if op and op|length >= i+1 %}
  11072. \t\t\t\t\t\t\t{% if op[i]['name'] %}
  11073. \t\t\t\t\t\t\t{% set hide_opt = false %}
  11074. \t\t\t\t\t\t\t{% if is_gs and (op[i]['name'] matches '/撤去/' or op[i]['name'] matches '/残土/') %}
  11075. \t\t\t\t\t\t\t\t{% set hide_opt = true %}
  11076. \t\t\t\t\t\t\t{% endif %}
  11077. \t\t\t\t\t\t\t{% if is_cg and op[i]['name'] matches '/残土/' %}
  11078. \t\t\t\t\t\t\t\t{% set hide_opt = true %}
  11079. \t\t\t\t\t\t\t{% endif %}
  11080. \t\t\t\t\t\t\t{% if not hide_opt %}
  11081. \t\t\t\t\t\t\t{# price=0 で「解体」「撤去」「設置場所」(wd 等で API 差額未提供) を含むオプションは
  11082. \t\t\t\t\t\t\t   選択時に「現場調査後に正式お見積もり」文言を出す. #}
  11083. \t\t\t\t\t\t\t{% set is_removal_unknown = (op[i]['price']|default(0) == 0 or op[i]['price']|default('0') == '0')
  11084. \t\t\t\t\t\t\t                              and (op[i]['name'] matches '/解体/' or op[i]['name'] matches '/撤去/' or op[i]['name'] matches '/設置場所/') %}
  11085. \t\t\t\t\t\t\t{# tf (人工芝, sale_type=6): ex-shop に施工価格がないため「取り付け工事も希望する」選択時に現地調査文言を表示 #}
  11086. \t\t\t\t\t\t\t{% set is_tf_kouji = (ProductClass.SaleType.id == 6 and op[i]['name'] matches '/取り付け工事/') %}
  11087. \t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-3\" data-op-idx=\"{{ i }}\" data-op-name=\"{{ op[i]['name']|e('html_attr') }}\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  11088. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">{{ op[i]['name'] }}{% if mitsumori_json and mitsumori_json.op[i] %}: <span>{{ mitsumori_json.op[i] }}</span>{% endif %}</div>
  11089. \t\t\t\t\t\t\t  {% if op[i]['comment'] %}<div class=\"opt-comment\" style=\"font-size:12px;color:#666;margin:4px 0 6px;\">{{ op[i]['comment'] }}</div>{% endif %}
  11090. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  11091. \t\t\t\t\t\t\t    {# off が空 (= ex-shop に選択肢が 1 つしかない基礎施工等) のときは on 側を
  11092. \t\t\t\t\t\t\t       既定選択にして 2 個目の空ラジオを描画しない. #}
  11093. \t\t\t\t\t\t\t    <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.op[i] == op[i]['on']) or not op[i]['off'] %} is-selected{% endif %}\"
  11094. \t\t\t\t\t\t\t           onclick=\"mitsumori_simulation('op{{ i }}','op{{ i }}_1');\">
  11095. \t\t\t\t\t\t\t      <input type=\"radio\" name=\"op{{ i }}\" id=\"op{{ i }}_1\" value=\"{{ op[i]['on'] }}\" {% if (mitsumori_json and mitsumori_json.op[i] == op[i]['on']) or not op[i]['off'] %}checked{% endif %}>
  11096. \t\t\t\t\t\t\t      {{ op[i]['on'] }}
  11097. \t\t\t\t\t\t\t    </label>
  11098. \t\t\t\t\t\t\t    {% if op[i]['off'] %}
  11099. \t\t\t\t\t\t\t    <label class=\"opt-btn{% if mitsumori_json and mitsumori_json.op[i] == op[i]['off'] %} is-selected{% endif %}\"
  11100. \t\t\t\t\t\t\t           onclick=\"mitsumori_simulation('op{{ i }}','op{{ i }}_2');\">
  11101. \t\t\t\t\t\t\t      <input type=\"radio\" name=\"op{{ i }}\" id=\"op{{ i }}_2\" value=\"{{ op[i]['off'] }}\" {% if mitsumori_json and mitsumori_json.op[i] == op[i]['off'] %}checked{% endif %}>
  11102. \t\t\t\t\t\t\t      {{ op[i]['off'] }}
  11103. \t\t\t\t\t\t\t    </label>
  11104. \t\t\t\t\t\t\t    {% endif %}
  11105. \t\t\t\t\t\t\t  </div>
  11106. \t\t\t\t\t\t\t  {% if is_removal_unknown or is_tf_kouji %}
  11107. \t\t\t\t\t\t\t  <div class=\"opt-survey-note\" data-op-idx=\"{{ i }}\" style=\"font-size:12px;color:#c00;margin-top:6px;{% if not (mitsumori_json and mitsumori_json.op[i] == op[i]['on']) %}display:none;{% endif %}\">
  11108. \t\t\t\t\t\t\t    ※ 現場調査後に正式お見積もりさせていただきます。
  11109. \t\t\t\t\t\t\t  </div>
  11110. \t\t\t\t\t\t\t  {% endif %}
  11111. \t\t\t\t\t\t\t</div>
  11112. \t\t\t\t\t\t\t{% endif %}
  11113. \t\t\t\t\t\t\t{% endif %}
  11114. \t\t\t\t\t\t\t{% endif %}
  11115. \t\t\t\t\t\t{% endfor %}
  11116. \t\t\t\t\t\t{# fe (sale_type=4) ブロックの種類×段数 サブ UI コンテナ.
  11117. \t\t\t\t\t\t   親オプション「ご希望のフェンス設置方法」 = 「新規にブロック積みを行う」
  11118. \t\t\t\t\t\t   を選択したときだけ JS (renderFeBlockRadios) で表示される. #}
  11119. \t\t\t\t\t\t{% if ProductClass.SaleType.id == 4 and oi and oi.fe_block %}
  11120. \t\t\t\t\t\t<div id=\"fe-block-options\" class=\"form-group mt-3 pb-3\" style=\"display:none;border-bottom:1px solid rgba(0,0,0,.125)\"></div>
  11121. \t\t\t\t\t\t{% endif %}
  11122. \t\t\t\t\t  </div>
  11123. \t\t\t\t\t  <!-- /.card-body -->
  11124. \t\t\t\t\t</div>
  11125.                     <form action=\"{{ url('product_add_cart', {id:Product.id}) }}\" method=\"post\" id=\"form1\" name=\"form1\">
  11126.                         {% if Product.stock_find %}
  11127.                             <div class=\"ec-productRole__actions\">
  11128.                                 {% if form.classcategory_id1 is defined %}
  11129.                                     <div class=\"ec-select\">
  11130.                                         {{ form_row(form.classcategory_id1) }}
  11131.                                         {{ form_errors(form.classcategory_id1) }}
  11132.                                     </div>
  11133.                                     {% if form.classcategory_id2 is defined %}
  11134.                                         <div class=\"ec-select\">
  11135.                                             {{ form_row(form.classcategory_id2) }}
  11136.                                             {{ form_errors(form.classcategory_id2) }}
  11137.                                         </div>
  11138.                                     {% endif %}
  11139.                                 {% endif %}
  11140.                                 <div class=\"ec-numberInput\">
  11141.                                     {{ form_widget(form.quantity, { type: 'hidden' }) }}
  11142.                                     {{ form_errors(form.quantity) }}
  11143.                                 </div>
  11144.                             </div>
  11145.                         {% else %}
  11146.                             <div class=\"ec-productRole__btn\">
  11147.                                 <button type=\"button\" class=\"ec-blockBtn--action\" disabled=\"disabled\">
  11148.                                     {{ 'ただいま品切れ中です。'|trans }}
  11149.                                 </button>
  11150.                             </div>
  11151.                         {% endif %}
  11152.                         <div class=\"ec-productRole__btn mt-3\">
  11153.                            <button type=\"submit\" id=\"cart_btn\" class=\"ec-blockBtn--action add-cart\">カートに入れる</button>
  11154.                         </div>
  11155.                         {{ form_rest(form) }}
  11156.                     </form>
  11157.                     <div class=\"ec-modal add-cart-modal\">
  11158.                         <div class=\"ec-modal-overlay\">
  11159.                             <div class=\"ec-modal-wrap add-cart-modal__wrap\">
  11160.                                 <span class=\"ec-modal-close\"><span class=\"ec-icon\"><img src=\"{{ asset('assets/icon/cross-dark.svg') }}\" alt=\"\"/></span></span>
  11161.                                 <div id=\"ec-modal-header\" class=\"text-center add-cart-modal__header\">{{ 'カートに追加しました。'|trans }}</div>
  11162.                                 <div class=\"ec-modal-box add-cart-modal__box\">
  11163.                                     <div class=\"ec-role add-cart-modal__actions\">
  11164.                                         <a href=\"{{ url('cart') }}\" class=\"ec-inlineBtn--action add-cart-modal__primary\">{{ 'カートに進む'|trans }}</a>
  11165.                                         <span class=\"ec-inlineBtn--cancel add-cart-modal__secondary\">{{ '商品検索を続ける'|trans }}</span>
  11166.                                     </div>
  11167.                                 </div>
  11168.                             </div>
  11169.                         </div>
  11170.                     </div>
  11171.                     <div class=\"ec-productRole__description\">{{ Product.description_detail|raw|nl2br }}
  11172.                     </div>
  11173.                     {# SNSシェア #}
  11174.                     <div class=\"ec-productRole__share\">
  11175.                         <ul class=\"ec-share\">
  11176.                             <li class=\"ec-share__item\">
  11177.                                 <a href=\"https://twitter.com/share?url={{ app.request.uri|url_encode }}&text={{ Product.name|url_encode }}\" class=\"ec-share__link ec-share__link--twitter\" target=\"_blank\" rel=\"noreferrer noopener\">
  11178.                                     <i class=\"fab fa-twitter\"></i>
  11179.                                 </a>
  11180.                             </li>
  11181.                             <li class=\"ec-share__item\">
  11182.                                 <a href=\"https://www.facebook.com/sharer/sharer.php?u={{ app.request.uri|url_encode }}\" class=\"ec-share__link ec-share__link--facebook\" target=\"_blank\" rel=\"noreferrer noopener\">
  11183.                                     <i class=\"fab fa-facebook-f\"></i>
  11184.                                 </a>
  11185.                             </li>
  11186.                             <li class=\"ec-share__item\">
  11187.                                 <a href=\"https://social-plugins.line.me/lineit/share?url={{ app.request.uri|url_encode }}\" class=\"ec-share__link ec-share__link--line\" target=\"_blank\" rel=\"noreferrer noopener\">
  11188.                                     <i class=\"fab fa-line\"></i>
  11189.                                 </a>
  11190.                             </li>
  11191.                         </ul>
  11192.                     </div>
  11193.                 </div>
  11194. \t\t\t\t{# ===== スマホ用 見積金額 下部固定バー ===== #}
  11195. \t\t\t\t<div id=\"sp-mitsumori-bar\">
  11196. \t\t\t\t    <div class=\"sp-bar__pricewrap\">
  11197. \t\t\t\t        <div class=\"sp-bar__label\">合計(工事費・税込)</div>
  11198. \t\t\t\t        <div class=\"sp-bar__price\" id=\"sp-mitsumori-price\">---円</div>
  11199. \t\t\t\t    </div>
  11200. \t\t\t\t    <button type=\"button\" class=\"sp-bar__detail-btn\"
  11201. \t\t\t\t            onclick=\"openSpMitsumoriDetail();\" title=\"お見積りの詳細(内訳)を表示\">
  11202. \t\t\t\t        <i class=\"far fa-file-alt\"></i>
  11203. \t\t\t\t        <span>詳細</span>
  11204. \t\t\t\t    </button>
  11205. \t\t\t\t    <button type=\"button\" class=\"sp-bar__btn\"
  11206. \t\t\t\t            onclick=\"document.getElementById('cart_btn2') && document.getElementById('cart_btn2').click();\">
  11207. \t\t\t\t        <i class=\"fas fa-shopping-cart\"></i>
  11208. \t\t\t\t        <span class=\"sp-bar__btn-label\">カートへ</span>
  11209. \t\t\t\t        {% set spTotalQty = get_carts_total_quantity() %}
  11210. \t\t\t\t        {% if spTotalQty > 0 %}
  11211. \t\t\t\t            <span class=\"sp-bar__cart-badge\">{{ spTotalQty|number_format }}</span>
  11212. \t\t\t\t        {% endif %}
  11213. \t\t\t\t    </button>
  11214. \t\t\t\t    <a href=\"{{ url('homepage') }}\" class=\"sp-bar__home-btn\" title=\"トップページへ\">
  11215. \t\t\t\t        <i class=\"fas fa-home\"></i>
  11216. \t\t\t\t    </a>
  11217. \t\t\t\t</div>
  11218. \t\t\t\t{# ===== スマホ用 お見積りの詳細 ボトムシート ===== #}
  11219. \t\t\t\t{# タップ時に現在の内訳カード(.mitsumori-card-pc)の中身を複製して表示する。
  11220. \t\t\t\t   価格計算には触れず、ライブ同期済みの表示値をそのまま見せる方式。 #}
  11221. \t\t\t\t<div id=\"sp-mitsumori-detail\" class=\"sp-detail-sheet\" aria-hidden=\"true\">
  11222. \t\t\t\t    <div class=\"sp-detail-sheet__overlay\" onclick=\"closeSpMitsumoriDetail();\"></div>
  11223. \t\t\t\t    <div class=\"sp-detail-sheet__panel\" role=\"dialog\" aria-label=\"お見積りの詳細\">
  11224. \t\t\t\t        <div class=\"sp-detail-sheet__header\">
  11225. \t\t\t\t            <span class=\"sp-detail-sheet__title\">お見積りの詳細</span>
  11226. \t\t\t\t            <button type=\"button\" class=\"sp-detail-sheet__close\" onclick=\"closeSpMitsumoriDetail();\" aria-label=\"閉じる\">&times;</button>
  11227. \t\t\t\t        </div>
  11228. \t\t\t\t        <div class=\"sp-detail-sheet__body\" id=\"sp-detail-body\"></div>
  11229. \t\t\t\t        <div class=\"sp-detail-sheet__footer\">
  11230. \t\t\t\t            <button type=\"button\" class=\"sp-detail-sheet__invoice\"
  11231. \t\t\t\t                    onclick=\"closeSpMitsumoriDetail(); document.getElementById('mitsumori_btn') && document.getElementById('mitsumori_btn').click();\">見積書を表示</button>
  11232. \t\t\t\t            <button type=\"button\" class=\"sp-detail-sheet__cart\"
  11233. \t\t\t\t                    onclick=\"closeSpMitsumoriDetail(); document.getElementById('cart_btn2') && document.getElementById('cart_btn2').click();\">カートに入れる</button>
  11234. \t\t\t\t        </div>
  11235. \t\t\t\t    </div>
  11236. \t\t\t\t</div>
  11237. \t\t\t\t{# tg カテゴリ用: block 別オプション差額ラジオ (W/D 確定後に JS が動的描画) #}
  11238. \t\t\t\t<div id=\"tg-options\" class=\"tg-options-container col-12\"></div>
  11239. \t\t\t\t<div class=\"card col-12 collapsed-card sticky-top float-right mitsumori-card-pc\">
  11240. \t\t\t\t\t<div class=\"card-header\">
  11241. \t\t\t\t\t  <h3 class=\"card-title\">現在のお見積り額</h3>
  11242. \t\t\t\t\t  <div class=\"card-tools\">
  11243. \t\t\t\t\t    <span class=\"float-left\" id=\"mitsumori_message\">395000円</span>
  11244. \t\t\t\t\t    <button type=\"button\" class=\"btn btn-tool btn-mitsumori-toggle\" data-card-widget=\"collapse\" title=\"詳細を表示\">
  11245. \t\t\t\t\t      <span class=\"toggle-icon\">▼ 詳細</span>
  11246. \t\t\t\t\t    </button>
  11247. \t\t\t\t\t  </div>
  11248. \t\t\t\t\t</div>
  11249. \t\t\t\t\t<div class=\"card-body p-0\">
  11250. \t\t\t\t\t  <ul class=\"nav nav-pills flex-column\">
  11251. \t\t\t\t\t    <li class=\"nav-item active\">
  11252. \t\t\t\t\t      <a class=\"nav-link\">
  11253. \t\t\t\t\t        <i class=\"far fa-file-alt\"></i> 合計(工事費・税込)
  11254. \t\t\t\t\t        <span class=\"float-right\" id=\"mitsumori_goukei\">395,000円</span>
  11255. \t\t\t\t\t      </a>
  11256. \t\t\t\t\t    </li>
  11257. \t\t\t\t\t    <li class=\"nav-item active\">
  11258. \t\t\t\t\t      <a class=\"nav-link\">
  11259. \t\t\t\t\t        <i class=\"far fa-file-alt\"></i> 商品価格
  11260. \t\t\t\t\t        <span class=\"float-right\" id=\"mitsumori_price\">307,008円</span>
  11261. \t\t\t\t\t      </a>
  11262. \t\t\t\t\t    </li>
  11263. \t\t\t\t\t    {# sale_type=2 (補助金窓) ではカタログ価格軸を使わないので非表示. JS 側で #maker_price には \"---円\" を入れる. #}
  11264. \t\t\t\t\t    {% if ProductClass.SaleType.id != 2 %}
  11265. \t\t\t\t\t    <li class=\"nav-item\">
  11266. \t\t\t\t\t      <a class=\"nav-link\">
  11267. \t\t\t\t\t        &nbsp;&nbsp;<i class=\"far fa-file-alt\"></i> カタログ価格
  11268. \t\t\t\t\t        <span class=\"float-right\" id=\"maker_price\">479,700円</span>
  11269. \t\t\t\t\t      </a>
  11270. \t\t\t\t\t    </li>
  11271. \t\t\t\t\t    {% else %}
  11272. \t\t\t\t\t    {# sale_type=2 でも JS が #maker_price を参照するので hidden で残す #}
  11273. \t\t\t\t\t    <span id=\"maker_price\" style=\"display:none;\">---円</span>
  11274. \t\t\t\t\t    {% endif %}
  11275. \t\t\t\t\t    <li class=\"nav-item\">
  11276. \t\t\t\t\t      <a class=\"nav-link\">
  11277. \t\t\t\t\t        &nbsp;&nbsp;<i class=\"far fa-file-alt\"></i>
  11278. \t\t\t\t\t        {% if ProductClass.SaleType.id == 2 %}補助金(割引額){% else %}お値引き{% endif %}
  11279. \t\t\t\t\t        <span class=\"float-right\" id=\"mitsumori_off\">-172,692円</span>
  11280. \t\t\t\t\t      </a>
  11281. \t\t\t\t\t    </li>
  11282. \t\t\t\t\t    {# 補助金窓のみ: 当店が申請代行する旨を補助金行の直下に小さく表示 (消費者の手続き勘違い防止) #}
  11283. \t\t\t\t\t    {% if ProductClass.SaleType.id == 2 %}
  11284. \t\t\t\t\t    <li class=\"nav-item\">
  11285. \t\t\t\t\t      <div style=\"padding:4px 12px 8px;color:#6c757d;font-size:11px;line-height:1.4;\">
  11286. \t\t\t\t\t        ※当店が補助金事業者として申請代行し、契約代金に充当します
  11287. \t\t\t\t\t      </div>
  11288. \t\t\t\t\t    </li>
  11289. \t\t\t\t\t    {% endif %}
  11290. \t\t\t\t\t    <li class=\"nav-item\">
  11291. \t\t\t\t\t      <a class=\"nav-link\">
  11292. \t\t\t\t\t        <i class=\"far fa-file-alt\"></i> 基本工事費
  11293. \t\t\t\t\t        <span class=\"float-right\" id=\"mitsumori_ct\">53,250円</span>
  11294. \t\t\t\t\t      </a>
  11295. \t\t\t\t\t    </li>
  11296. \t\t\t\t\t    <li class=\"nav-item\">
  11297. \t\t\t\t\t      <a class=\"nav-link\">
  11298. \t\t\t\t\t        <i class=\"far fa-file-alt\"></i> 施工オプション
  11299. \t\t\t\t\t        <span class=\"float-right\"id=\"mitsumori_option\">6,297円</span>
  11300. \t\t\t\t\t      </a>
  11301. \t\t\t\t\t    </li>
  11302. \t\t\t\t\t  </ul>
  11303. \t\t\t\t\t</div>
  11304. \t\t\t\t\t<div class=\"card-footer\">
  11305. \t\t                <button type=\"button\" id=\"mitsumori_btn\" class=\"btn btn-info\" data-toggle=\"modal\" data-target=\"#modal-mitsumori\">
  11306. \t\t                  見積書表示
  11307. \t\t                </button>
  11308.                         <button type=\"submit\" id=\"cart_btn2\" class=\"btn btn-info add-cart\">カートに入れる</button>
  11309. \t\t\t\t\t</div>
  11310. \t\t\t\t</div>
  11311.             </div>
  11312.         </div>
  11313.     </div>
  11314.   <div class=\"modal\" id=\"modal-mitsumori\">
  11315.     <div class=\"modal-dialog modal-mitsumori\" style=\"max-width:1000px\">
  11316.       <div class=\"modal-content\">
  11317.         <div class=\"modal-header\">
  11318.           <h4 class=\"modal-title\">お見積書</h4>
  11319.           <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Close\">
  11320.             <span aria-hidden=\"true\">&times;</span>
  11321.           </button>
  11322.         </div>
  11323.         <div class=\"modal-body\">
  11324. \t\t\t<div class=\"invoice p-3 mb-5\" style=\"max-width:1000px; margin:auto;\">
  11325. \t\t\t  <!-- title row -->
  11326. \t\t\t  <div class=\"row\">
  11327. \t\t\t    <div class=\"col-12\">
  11328. \t\t\t      <h2>概算お見積書 
  11329. \t\t\t        <small class=\"float-right\" style=\"font-size:14px;\">発行日: 2025/03/14</small>
  11330. \t\t\t      </h2>
  11331. \t\t\t    </div>
  11332. \t\t\t    <!-- /.col -->
  11333. \t\t\t  </div>
  11334. \t\t\t  <!-- info row -->
  11335. \t\t\t  <div class=\"row invoice-info\">
  11336. \t\t\t    <div class=\"col-sm-8 invoice-col\">
  11337. \t\t\t      <h3>お客様</h3>
  11338. \t\t\t      <span>下記の通り、お見積もり申し上げます。</span>
  11339. \t\t\t      <br />
  11340. \t\t\t      <br / >
  11341. \t\t\t      <br />
  11342. \t\t\t      <h2>お見積金額: <span id=\"mitsumori_kei\">399,080円</span></h2>
  11343. \t\t\t      <span>
  11344. \t\t\t        <br/>
  11345. \t\t\t        <br/>
  11346. \t\t\t        <br/>
  11347. \t\t\t        <br/>
  11348. \t\t\t      </span>
  11349. \t\t\t    </div>
  11350. \t\t\t    <div class=\"col-sm-4 invoice-col\">
  11351. \t\t\t      <p>
  11352. \t\t\t        <img alt=\"\" src=\"/html/user_data/js/images/logo.png\" style=\"width: 260px; max-width: 100%; max-height: 10mm;\">
  11353. \t\t\t      </p>
  11354. \t\t\t      <p>有限会社プラス</p>
  11355. \t\t\t      <p>〒400-0334</p>
  11356. \t\t\t      <p>山梨県南アルプス市藤田1450番地2</p>
  11357. \t\t\t      <p>TEL: 055-284-6480</p>
  11358. \t\t\t      <img alt=\"\" src=\"/html/user_data/js/images/seal.svg\" style=\"z-index: 2; position: absolute; width: 21mm; left: 58mm; top: 36mm;\">
  11359. \t\t\t    </div>
  11360. \t\t\t    <!-- /.col -->
  11361. \t\t\t    <!-- /.col -->
  11362. \t\t\t  </div>
  11363. \t\t\t  <!-- /.row -->
  11364. \t\t\t  <!-- Table row -->
  11365. \t\t\t  <div class=\"row\">
  11366. \t\t\t    <div class=\"col-12 table-responsive\">
  11367. \t\t\t      <table class=\"table table-striped\">
  11368. \t\t\t        <thead>
  11369. \t\t\t          <tr>
  11370. \t\t\t            <th>項目</th>
  11371. \t\t\t            <th>数量</th>
  11372. \t\t\t            <th>単位</th>
  11373. \t\t\t            <th>単価</th>
  11374. \t\t\t            <th>小計</th>
  11375. \t\t\t          </tr>
  11376. \t\t\t        </thead>
  11377. \t\t\t        <tbody>
  11378. \t\t\t          <tr>
  11379. \t\t\t            <td id=\"mitsumori_item_name\">{{ Product.name }}</td>
  11380. \t\t\t            <td>1</td>
  11381. \t\t\t            <td>式</td>
  11382. \t\t\t            <td id=\"mitsumori_price_01\">352,800</td>
  11383. \t\t\t            <td id=\"mitsumori_price_02\">352,800</td>
  11384. \t\t\t          </tr>
  11385. \t\t\t          <tr>
  11386. \t\t\t            <td>基本工事費</td>
  11387. \t\t\t            <td>1</td>
  11388. \t\t\t            <td>式</td>
  11389. \t\t\t            <td id=\"mitsumori_ct_01\">10,000</td>
  11390. \t\t\t            <td id=\"mitsumori_ct_02\">10,000</td>
  11391. \t\t\t          </tr>
  11392. \t\t\t          <tr>
  11393. \t\t\t            <td>残土・ガラ処理</td>
  11394. \t\t\t            <td>1</td>
  11395. \t\t\t            <td>式</td>
  11396. \t\t\t            <td>0円</td>
  11397. \t\t\t            <td></td>
  11398. \t\t\t          </tr>
  11399. \t\t\t          <tr>
  11400. \t\t\t            <td> </td>
  11401. \t\t\t            <td></td>
  11402. \t\t\t            <td></td>
  11403. \t\t\t            <td></td>
  11404. \t\t\t            <td></td>
  11405. \t\t\t          </tr>
  11406. \t\t\t        </tbody>
  11407. \t\t\t      </table>
  11408. \t\t\t    </div>
  11409. \t\t\t    <!-- /.col -->
  11410. \t\t\t  </div>
  11411. \t\t\t  <!-- /.row -->
  11412. \t\t\t  <div class=\"row\">
  11413. \t\t\t    <!-- accepted payments column -->
  11414. \t\t\t    <div class=\"col-6\">
  11415. \t\t\t      <p class=\"lead\">お支払い方法</p>
  11416. \t\t\t      <p class=\"text-muted well well-sm shadow-none\" style=\"margin-top: 10px;\">銀行振込、クレジットカード決済、PAYPAY決済
  11417. \t\t\t        <br>銀行振込:山梨中央銀行 白根支店 普通口座 391402
  11418. \t\t\t        <br>※商品代金と工事代金の総額が金100万円(税込)を超える場合、着手金として代金の半額をご契約後お支払いいただきます。 
  11419. \t\t\t      </p>
  11420. \t\t\t    </div>
  11421. \t\t\t    <!-- /.col -->
  11422. \t\t\t    <div class=\"col-6\">
  11423. \t\t\t      <div class=\"table-responsive\">
  11424. \t\t\t        <table class=\"table\">
  11425. \t\t\t          <tbody>
  11426. \t\t\t            <tr>
  11427. \t\t\t              <th style=\"width:50%\">小計:</th>
  11428. \t\t\t              <td id=\"mitsumori_shoukei\">362,800</td>
  11429. \t\t\t            </tr>
  11430. \t\t\t            <tr>
  11431. \t\t\t              <th>消費税 (10%)</th>
  11432. \t\t\t              <td id=\"mitsumori_tax\">36,280</td>
  11433. \t\t\t            </tr>
  11434. \t\t\t            <tr>
  11435. \t\t\t              <th>合計:</th>
  11436. \t\t\t              <td id=\"mitsumori_goukei_02\">399,080</td>
  11437. \t\t\t            </tr>
  11438. \t\t\t          </tbody>
  11439. \t\t\t        </table>
  11440. \t\t\t      </div>
  11441. \t\t\t    </div>
  11442. \t\t\t    <!-- /.col -->
  11443. \t\t\t  </div>
  11444. \t\t\t  <!-- /.row -->
  11445. \t\t\t</div>
  11446.         </div>
  11447.         <div class=\"modal-footer justify-content-between\">
  11448. \t\t\t      {# PDF出力: mitsumori_json を POST して PDF ダウンロード #}
  11449. \t\t\t      <form method=\"post\" action=\"{{ url('mitsumori_pdf') }}\" target=\"_blank\" id=\"pdf_download_form\">
  11450. \t\t\t        <input type=\"hidden\" name=\"_token\" value=\"{{ csrf_token('mitsumori_pdf') }}\">
  11451. \t\t\t        <input type=\"hidden\" name=\"mitsumori_json\" id=\"pdf_mitsumori_json\">
  11452. \t\t\t        <button type=\"submit\" class=\"btn btn-primary float-right\" style=\"margin-right: 5px;\" onclick=\"syncPdfJson();\">
  11453. \t\t\t          <i class=\"fas fa-download\"></i>PDF出力
  11454. \t\t\t        </button>
  11455. \t\t\t      </form>
  11456.                   <button type=\"submit\" id=\"cart_btn3\" class=\"btn btn-info add-cart\">カートに入れる</button>
  11457.         </div>
  11458.       </div>
  11459.       <!-- /.modal-content -->
  11460.     </div>
  11461.     <!-- /.modal-dialog -->
  11462.   </div>
  11463.   <!-- /.modal -->
  11464.     <!-- Image zoom modal: custom lightweight lightbox (no CDN dependency) -->
  11465.     <div id=\"img-modal\" role=\"dialog\" aria-modal=\"true\" aria-label=\"画像拡大\">
  11466.         <button id=\"img-modal__close\" aria-label=\"閉じる\">&times;</button>
  11467.         <button id=\"img-modal__prev\" aria-label=\"前の画像\">&#10094;</button>
  11468.         <img id=\"img-modal__img\" src=\"\" alt=\"\">
  11469.         <button id=\"img-modal__next\" aria-label=\"次の画像\">&#10095;</button>
  11470.     </div>
  11471.     <style>
  11472.     #img-modal {
  11473.         display: none;
  11474.         position: fixed;
  11475.         inset: 0;
  11476.         z-index: 9999;
  11477.         background: rgba(0,0,0,0.88);
  11478.         align-items: center;
  11479.         justify-content: center;
  11480.         cursor: zoom-out;
  11481.     }
  11482.     #img-modal.is-open { display: flex; }
  11483.     #img-modal__img {
  11484.         max-width: 92vw;
  11485.         max-height: 88vh;
  11486.         object-fit: contain;
  11487.         border-radius: 4px;
  11488.         cursor: default;
  11489.         user-select: none;
  11490.         touch-action: pinch-zoom;
  11491.         display: block;
  11492.     }
  11493.     #img-modal__close {
  11494.         position: absolute;
  11495.         top: 14px;
  11496.         right: 18px;
  11497.         font-size: 38px;
  11498.         color: #fff;
  11499.         cursor: pointer;
  11500.         background: none;
  11501.         border: none;
  11502.         padding: 0;
  11503.         line-height: 1;
  11504.         z-index: 1;
  11505.         opacity: 0.85;
  11506.     }
  11507.     #img-modal__close:hover { opacity: 1; }
  11508.     #img-modal__prev,
  11509.     #img-modal__next {
  11510.         position: absolute;
  11511.         top: 50%;
  11512.         transform: translateY(-50%);
  11513.         font-size: 36px;
  11514.         color: #fff;
  11515.         cursor: pointer;
  11516.         background: rgba(0,0,0,0.32);
  11517.         border: none;
  11518.         padding: 10px 16px;
  11519.         line-height: 1;
  11520.         border-radius: 6px;
  11521.         z-index: 1;
  11522.         opacity: 0.8;
  11523.         user-select: none;
  11524.     }
  11525.     #img-modal__prev:hover, #img-modal__next:hover { opacity: 1; }
  11526.     #img-modal__prev { left: 12px; }
  11527.     #img-modal__next { right: 12px; }
  11528.     @media (max-width: 767px) {
  11529.         #img-modal__prev, #img-modal__next { font-size: 28px; padding: 8px 12px; }
  11530.     }
  11531.     </style>
  11532.     <script>
  11533.     (function(){
  11534.         var images = [];
  11535.         var current = 0;
  11536.         // Collect original (non-cloned) slide images at click time.
  11537.         // After Slick init, slides are wrapped in .slick-slide; clones have .slick-cloned.
  11538.         function collectImages() {
  11539.             images = [];
  11540.             var \$slides = \$('.item_visual .slick-slide:not(.slick-cloned)');
  11541.             if (!\$slides.length) {
  11542.                 // Slick not yet initialized (fallback)
  11543.                 \$slides = \$('.item_visual .slide-item');
  11544.             }
  11545.             \$slides.each(function() {
  11546.                 var \$a = \$(this).find('a.js-zoom');
  11547.                 if (\$a.length) {
  11548.                     images.push({ src: \$a.attr('href'), alt: \$a.find('img').attr('alt') || '' });
  11549.                 }
  11550.             });
  11551.         }
  11552.         function showImage(idx) {
  11553.             current = ((idx % images.length) + images.length) % images.length;
  11554.             \$('#img-modal__img').attr({ src: images[current].src, alt: images[current].alt });
  11555.         }
  11556.         function openModal(href) {
  11557.             collectImages();
  11558.             if (!images.length) return;
  11559.             var idx = 0;
  11560.             for (var i = 0; i < images.length; i++) {
  11561.                 if (images[i].src === href) { idx = i; break; }
  11562.             }
  11563.             showImage(idx);
  11564.             \$('#img-modal').addClass('is-open');
  11565.             \$('body').css('overflow', 'hidden');
  11566.         }
  11567.         function closeModal() {
  11568.             \$('#img-modal').removeClass('is-open');
  11569.             \$('body').css('overflow', '');
  11570.         }
  11571.         // Click handler: works for both original and Slick-cloned anchors
  11572.         \$(document).on('click', '.item_visual a.js-zoom', function(e) {
  11573.             e.preventDefault();
  11574.             openModal(\$(this).attr('href'));
  11575.         });
  11576.         // Close on backdrop click
  11577.         \$('#img-modal').on('click', function(e) {
  11578.             if (e.target === this) closeModal();
  11579.         });
  11580.         \$('#img-modal__close').on('click', closeModal);
  11581.         \$('#img-modal__prev').on('click', function(e) { e.stopPropagation(); showImage(current - 1); });
  11582.         \$('#img-modal__next').on('click', function(e) { e.stopPropagation(); showImage(current + 1); });
  11583.         // Keyboard navigation
  11584.         \$(document).on('keydown', function(e) {
  11585.             if (!\$('#img-modal').hasClass('is-open')) return;
  11586.             if (e.key === 'Escape') closeModal();
  11587.             if (e.key === 'ArrowLeft') showImage(current - 1);
  11588.             if (e.key === 'ArrowRight') showImage(current + 1);
  11589.         });
  11590.         // Touch swipe (horizontal only)
  11591.         var _tx = 0;
  11592.         var \$modal = document.getElementById('img-modal');
  11593.         \$modal.addEventListener('touchstart', function(e) {
  11594.             _tx = e.changedTouches[0].clientX;
  11595.         }, { passive: true });
  11596.         \$modal.addEventListener('touchend', function(e) {
  11597.             var dx = e.changedTouches[0].clientX - _tx;
  11598.             if (Math.abs(dx) > 48) {
  11599.                 dx < 0 ? showImage(current + 1) : showImage(current - 1);
  11600.             }
  11601.         }, { passive: true });
  11602.     })();
  11603.     </script>
  11604. {% endblock %}
  11605. ""Product/detail.twig""/home/xs538259/exterior-plus.jp/public_html/app/template/default/Product/detail.twig");
  11606.     }
  11607. }