diff --git a/app.rb b/app.rb
index 1e568eb..800a228 100644
--- a/app.rb
+++ b/app.rb
@@ -14,6 +14,7 @@ require_relative "classes/config"
 require_relative "classes/gitinfo"
 require_relative "classes/db"
 require_relative "classes/systeminfo"
+require_relative "classes/utilities"
 
 def print_error_page(error_status, error_meaasge)
   @page_name = "Ошибка выполнения"
@@ -22,14 +23,6 @@ def print_error_page(error_status, error_meaasge)
   halt erb(:page5xx)
 end
 
-def sanitize_filename(filename)
-  filename = filename.strip
-  sanitized = filename.gsub(/[^a-zA-Z0-9_]/, "_")
-  sanitized.gsub!(/_+/, "_")
-  sanitized.gsub!(/^_+|_+$/, "")
-  sanitized
-end
-
 cfg = IniConfig.new()
 db = DBase.new()
 
@@ -155,11 +148,118 @@ get "/recips" do
   erb :receips
 end
 
+get "/recips/:rcp_id" do
+  repo = GitRepo.new(cfg.get_repo, db)
+  if repo.path.nil?
+    print_error_page(503, "Путь к репозиториям не существует")
+  else
+    @repo_data = repo.getrepos
+    @rcp_id = params["rcp_id"]
+    info = db.get_rcp_info_by_id(@rcp_id)
+    @page_name = info[:filepath]
+    @rcp_name = info[:filepath]
+    if session[:rcp_old_description].nil?
+      @old_filepath = info[:filepath]
+    else
+      @old_filepath = session[:rcp_old_filepath]
+    end
+    if session[:rcp_old_description].nil?
+      @old_description = info[:descr]
+    else
+      @old_description = session[:rcp_old_description]
+    end
+    if session[:rcp_old_codedata].nil?
+      @old_codedata = info[:content]
+    else
+      @old_codedata = session[:rcp_old_codedata]
+    end
+    if session[:rcp_old_gitlst].nil?
+      @old_gitlst = info[:repos_list]
+    else
+      @old_gitlst = session[:rcp_old_gitlst]
+    end
+    @error_data = session[:rcpcreate_error]
+    session[:rcpcreate_error] = nil
+    session[:rcp_old_filepath] = nil
+    session[:rcp_old_description] = nil
+    session[:rcp_old_codedata] = nil
+    session[:rcp_old_gitlst] = nil
+    erb :rcpedit
+  end
+end
+
+post "/recips/:rcp_id" do
+  rcp_id = params["rcp_id"]
+  session[:rcp_old_filepath] = params["filepath"]
+  session[:rcp_old_description] = params["description"]
+  session[:rcp_old_codedata] = params["codedata"]
+  session[:rcp_old_gitlst] = params["gitlst"]
+  if params["filepath"].nil? || params["description"].nil? || params["filepath"].strip == "" || params["description"].strip == ""
+    session[:rcpcreate_error] = "Имя рецепта и описание не должны быть пустыми"
+    redirect url("/recips/#{rcp_id}")
+  else
+    @error_data = db.updaterecip(rcp_id, params["filepath"], params["description"], params["codedata"], params["gitlst"])
+    unless @error_data.nil?
+      session[:rcpcreate_error] = @error_data
+      redirect url("/recips/#{rcp_id}")
+    else
+      redirect "/recips"
+    end
+  end
+end
+
+post "/rcpdelete/:rcp_id" do
+  input_name = params["rcpnamedup"]
+  rcp_id = params["rcp_id"]
+  info = db.get_rcp_info_by_id(rcp_id)
+  if info.nil?
+    print_error_page(404, "Рецепта не существует")
+  else
+    if info[:filepath] == input_name
+      db.delete_rcp(rcp_id)
+    end
+    redirect "/recips"
+  end
+end
+
+post "/rcpdelete" do
+  redirect "/recips"
+end
+
 get "/rcpcreate" do
   @page_name = "Создать новый рецепт"
-  @error_data = session[:rcpcreate_error]
-  session[:gitcreate_error] = nil
-  erb :rcpcrt
+  @old_filepath = session[:rcp_old_filepath]
+  @old_description = session[:rcp_old_description]
+  @old_codedata = session[:rcp_old_codedata]
+  @old_gitlst = session[:rcp_old_gitlst]
+  repo = GitRepo.new(cfg.get_repo, db)
+  if repo.path.nil?
+    print_error_page(503, "Путь к репозиториям не существует")
+  else
+    @repo_data = repo.getrepos
+    @error_data = session[:rcpcreate_error]
+    session[:rcpcreate_error] = nil
+    erb :rcpcrt
+  end
+end
+
+post "/rcpcreate" do
+  session[:rcp_old_filepath] = params["filepath"]
+  session[:rcp_old_description] = params["description"]
+  session[:rcp_old_codedata] = params["codedata"]
+  session[:rcp_old_gitlst] = params["gitlst"]
+  if params["filepath"].nil? || params["description"].nil? || params["filepath"].strip == "" || params["description"].strip == ""
+    session[:rcpcreate_error] = "Имя рецепта и описание не должны быть пустыми"
+    redirect "/rcpcreate"
+  else
+    @error_data = db.createrecip(params["filepath"], params["description"], params["codedata"], params["gitlst"])
+    unless @error_data.nil?
+      session[:rcpcreate_error] = @error_data
+      redirect "/rcpcreate"
+    else
+      redirect "/recips"
+    end
+  end
 end
 
 not_found do
diff --git a/classes/db.rb b/classes/db.rb
index c57ac48..77188d9 100644
--- a/classes/db.rb
+++ b/classes/db.rb
@@ -17,8 +17,8 @@ class DBase
 
   def creategit(project_name, description)
     @error = nil
-    data = Repos.where(reponame: project_name)
-    unless data.nil?
+    data = Repos.where(reponame: project_name).first
+    if data.nil?
       id = Repos.insert(reponame: project_name, descr: description, public: 1)
       @last_id = id
     else
@@ -46,4 +46,66 @@ class DBase
       Repos.where(id: id).delete
     end
   end
+
+  def createrecip(filepath, description, codedata, gitlist)
+    error_data = nil
+    filepath_san = sanitize_rcptname(filepath)
+    is_data = Recips.where(filepath: filepath_san).first
+    if codedata.nil? || codedata.strip == ""
+      error_data
+    else
+      if is_data.nil?
+        id = Recips.insert(filepath: filepath_san, descr: description, content: codedata)
+        @last_id = id
+        if !gitlist.nil? && gitlist.length > 0
+          gitlist.each do |item|
+            data = Repos.where(id: item.to_i).first
+            unless data.nil?
+              RepocRecips.insert(repo_id: data[:id], recip_id: id)
+            end
+          end
+        end
+        error_data
+      else
+        "Рецепт с таким именем #{filepath_san} уже существует"
+      end
+    end
+  end
+
+  def updaterecip(id, filepath, description, codedata, gitlist)
+    error_data = nil
+    filepath_san = sanitize_rcptname(filepath)
+    is_data = Recips.where(filepath: filepath_san).first
+    if codedata.nil? || codedata.strip == ""
+      error_data
+    else
+      unless is_data.nil?
+        Recips.where(id: id.to_i).update(filepath: filepath_san, descr: description, content: codedata)
+        RepocRecips.where(recip_id: id.to_i).delete
+        if !gitlist.nil? && gitlist.length > 0
+          gitlist.each do |item|
+            data = Repos.where(id: item.to_i).first
+            unless data.nil?
+              RepocRecips.insert(repo_id: data[:id], recip_id: id)
+            end
+          end
+        end
+        error_data
+      else
+        "Рецепт с таким именем #{filepath_san} не существует"
+      end
+    end
+  end
+
+  def get_rcp_info_by_id(rcpi_id)
+    info = Recips[rcpi_id.to_i]
+    gits = RepocRecips.where(recip_id: info[:id])
+    info[:repos_list] = gits.map { |item| item[:repo_id].to_s }
+    info
+  end
+
+  def delete_rcp(id)
+    RepocRecips.where(recip_id: id.to_i).delete
+    Recips.where(id: id.to_i).delete
+  end
 end
diff --git a/classes/gitinfo.rb b/classes/gitinfo.rb
index 91f0f86..0faff98 100644
--- a/classes/gitinfo.rb
+++ b/classes/gitinfo.rb
@@ -67,13 +67,13 @@ class GitRepo
         db_info = @db.get_repo_info_by_name(repo_name)
         unless db_info.nil?
           db_info = db_info.first
-          repos_data << { :reponame => db_info.reponame, :descr => db_info.descr, :public => db_info.public }
+          repos_data << { :reponame => db_info.reponame, :descr => db_info.descr, :public => db_info.public, :id => db_info.id }
         else
           result = create_git_db_only(repo_name)
           if result.nil?
             db_info = @db.get_repo_info_by_name(repo_name)
             db_info = db_info.first
-            repos_data << { :reponame => db_info.reponame, :descr => db_info.descr, :public => db_info.public }
+            repos_data << { :reponame => db_info.reponame, :descr => db_info.descr, :public => db_info.public, :id => db_info.id }
           end
         end
       end
diff --git a/classes/utilities.rb b/classes/utilities.rb
new file mode 100644
index 0000000..ca4b704
--- /dev/null
+++ b/classes/utilities.rb
@@ -0,0 +1,15 @@
+def sanitize_filename(filename)
+  filename = filename.strip
+  sanitized = filename.gsub(/[^a-zA-Z0-9_]/, "_")
+  sanitized.gsub!(/_+/, "_")
+  sanitized.gsub!(/^_+|_+$/, "")
+  sanitized
+end
+
+def sanitize_rcptname(filename)
+  filename = filename.strip
+  sanitized = filename.gsub(/[^a-zA-Z0-9_\.]/, "_")
+  sanitized.gsub!(/_+/, "_")
+  sanitized.gsub!(/^_+|_+$/, "")
+  sanitized
+end
diff --git a/db/migrations/202502150000000_create.rb b/db/migrations/202502150000000_create.rb
index 1be9a62..dce80c3 100644
--- a/db/migrations/202502150000000_create.rb
+++ b/db/migrations/202502150000000_create.rb
@@ -27,7 +27,7 @@ Sequel.migration do
       primary_key :id
       String :content, text: true
       String :filepath, text: true
-      String :desct, text: true
+      String :descr, text: true
       Datetime :create_at, default: Sequel.lit("CURRENT_TIMESTAMP")
     end
 
diff --git a/public/js/jquery.dropdown.min.css b/public/js/jquery.dropdown.min.css
new file mode 100755
index 0000000..b3e2cfe
--- /dev/null
+++ b/public/js/jquery.dropdown.min.css
@@ -0,0 +1 @@
+@-webkit-keyframes iui-fadeIn{0%{opacity:0}100%{opacity:1}}@-moz-keyframes iui-fadeIn{0%{opacity:0}100%{opacity:1}}@-ms-keyframes iui-fadeIn{0%{opacity:0}100%{opacity:1}}@-o-keyframes iui-fadeIn{0%{opacity:0}100%{opacity:1}}@keyframes iui-fadeIn{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes iui-fadeOut{0%{opacity:1}100%{opacity:0}}@-moz-keyframes iui-fadeOut{0%{opacity:1}100%{opacity:0}}@-ms-keyframes iui-fadeOut{0%{opacity:1}100%{opacity:0}}@-o-keyframes iui-fadeOut{0%{opacity:1}100%{opacity:0}}@keyframes iui-fadeOut{0%{opacity:1}100%{opacity:0}}.dropdown-multiple,.dropdown-multiple-label,.dropdown-single{position:relative}.dropdown-multiple-label.active .dropdown-main,.dropdown-multiple.active .dropdown-main,.dropdown-single.active .dropdown-main{display:block;-webkit-animation:iui-fadeIn .2s ease-in forwards;-moz-animation:iui-fadeIn .2s ease-in forwards;-ms-animation:iui-fadeIn .2s ease-in forwards;-o-animation:iui-fadeIn .2s ease-in forwards;animation:iui-fadeIn .2s ease-in forwards}.dropdown-multiple-label.active .dropdown-display-label:after,.dropdown-multiple-label.active .dropdown-display:after,.dropdown-multiple.active .dropdown-display-label:after,.dropdown-multiple.active .dropdown-display:after,.dropdown-single.active .dropdown-display-label:after,.dropdown-single.active .dropdown-display:after{border-top:none;border-bottom:10px solid #999;border-left:5px solid transparent;border-right:5px solid transparent}.dropdown-multiple-label.active .dropdown-display,.dropdown-multiple-label.active .dropdown-display-label,.dropdown-multiple.active .dropdown-display,.dropdown-multiple.active .dropdown-display-label,.dropdown-single.active .dropdown-display,.dropdown-single.active .dropdown-display-label{border-bottom-left-radius:0;border-bottom-right-radius:0}.dropdown-display,.dropdown-display-label{position:relative;display:block;margin-bottom:0;font-size:14px;line-height:1.42857143;vertical-align:middle;touch-action:manipulation;cursor:pointer;user-select:none;background-image:none;border:1px solid #ccc;border-radius:4px;color:#333;background-color:#fff}.dropdown-display-label:after,.dropdown-display:after{content:'';position:absolute;border-top:10px solid #999;border-left:5px solid transparent;border-right:5px solid transparent;top:12px;right:8px}.dropdown-clear-all{background-color:#fff;border:none;font-size:22px;z-index:999;color:#999;position:absolute;right:2px;top:2px;display:none;width:25px;height:30px;text-align:center;line-height:30px}.dropdown-clear-all:focus{outline:0}.dropdown-clear-all:hover{color:#ccc;text-decoration:none}.dropdown-display{white-space:nowrap;padding:6px 20px 6px 12px}.dropdown-multiple:hover .dropdown-clear-all,.dropdown-single:hover .dropdown-clear-all{display:block}.dropdown-display .dropdown-chose-list{display:inline-block;vertical-align:middle;width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dropdown-display .dropdown-chose-list span:before{content:','}.dropdown-display .dropdown-chose-list span:first-child:before{content:''}.dropdown-display .placeholder{display:none}.dropdown-display .placeholder:first-child{position:absolute;height:100%;width:100%;top:0;left:0;color:#999;display:block;text-indent:10px;font-size:13px;line-height:32px}.dropdown-display input{border:0;outline:0}.dropdown-display-label{cursor:text;padding:6px 25px 5px 0}.dropdown-display-label .dropdown-search{display:inline-block}.dropdown-display-label input,.dropdown-display-label input:focus{border:none;outline:0}.dropdown-display-label .dropdown-chose-list{display:inline-block;padding:0 5px}.dropdown-display-label .dropdown-chose-list .placeholder{display:none}.dropdown-display-label .dropdown-selected{position:relative;margin:0 5px 5px 0;padding:0 20px 0 5px;border:1px solid #aaa;max-width:100%;border-radius:3px;background-repeat:repeat-x;color:#333;cursor:default;display:inline-block}.dropdown-display-label .dropdown-selected .del{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0;float:right;line-height:1;color:#999;position:absolute;right:3px;top:0}.dropdown-display-label .dropdown-selected .del:after{content:'\D7';font-size:16px}.dropdown-main{position:absolute;top:100%;left:0;z-index:1010;width:100%;color:#444;box-sizing:border-box;background-color:#fff;border:1px solid #ccc;border-radius:0 0 4px 4px;box-shadow:0 6px 12px rgba(0,0,0,.175);margin-top:-1px;border-top:0;padding:4px 7px;display:none}.dropdown-main ul{overflow-x:hidden;overflow-y:auto;max-height:240px;margin:0;padding:0}.dropdown-main input{margin-top:0;display:block;box-sizing:border-box;height:30px;border:1px solid #ccc;width:100%;text-indent:5px;border-radius:3px}.dropdown-main .dropdown-search{display:block;padding:5px 0}.dropdown-group{font-weight:700}.dropdown-group,.dropdown-option{margin:0;padding-left:12px;list-style:none;line-height:26px;word-wrap:break-word}.dropdown-option{cursor:pointer}.dropdown-option:focus,.dropdown-option:hover{background-color:#efefef;outline:0}.dropdown-option[disabled]{color:#ddd;background-color:#fff;cursor:not-allowed;text-decoration:line-through}.dropdown-option.dropdown-chose:after{content:'';float:right;width:10px;height:10px;background:#4AB1E9;border-radius:100%;margin:8px 5px 0 0}.dropdown-maxItem-alert,.dropdown-minItem-alert{position:absolute;top:0;left:0;background-color:#e4e3e2;width:100%;height:39px;line-height:39px;padding:0 5px;border-radius:5px;color:#999;-webkit-animation:iui-fadeIn .2s ease-in forwards;-moz-animation:iui-fadeIn .2s ease-in forwards;-ms-animation:iui-fadeIn .2s ease-in forwards;-o-animation:iui-fadeIn .2s ease-in forwards;animation:iui-fadeIn .2s ease-in forwards}
diff --git a/public/js/jquery.dropdown.min.js b/public/js/jquery.dropdown.min.js
new file mode 100755
index 0000000..81b256c
--- /dev/null
+++ b/public/js/jquery.dropdown.min.js
@@ -0,0 +1 @@
+(function (e) { "use strict"; function o() { } function n(e, o, n) { var t, i, l, a = null, d = 0; n || (n = {}); var s = function () { d = n.leading === !1 ? 0 : (new Date).getTime(), a = null, l = e.apply(t, i), a || (t = i = null) }; return function () { var r = (new Date).getTime(); d || n.leading !== !1 || (d = r); var c = o - (r - d); return t = this, i = arguments, c <= 0 || c > o ? (clearTimeout(a), a = null, d = r, l = e.apply(t, i), a || (t = i = null)) : a || n.trailing === !1 || (a = setTimeout(s, c)), l } } function t() { var e = this.isLabelMode, o = this.config.searchable, n = o ? '<span class="dropdown-search">' + this.config.input + "</span>" : ""; return e ? '<div class="dropdown-display-label"><div class="dropdown-chose-list">' + n + '</div></div><div class="dropdown-main">{{ul}}</div>' : '<a href="javascript:;" class="dropdown-display" tabindex="0"><span class="dropdown-chose-list"></span><a href="javascript:;"  class="dropdown-clear-all" tabindex="0">×</a></a><div class="dropdown-main">' + n + "{{ul}}</div>" } function i() { var o = this, n = o.config, t = o.$el, i = t.find(".dropdown-minItem-alert"), l = n.minCountErrorMessage; clearTimeout(o.itemCountAlertTimer), 0 === i.length && (l || (l = "Минимальный выбор" + n.minCount + "个"), i = e('<div class="dropdown-minItem-alert">' + l + "</div>")), t.append(i), o.itemCountAlertTimer = setTimeout(function () { t.find(".dropdown-minItem-alert").remove() }, f) } function l() { var o = this, n = o.config, t = o.$el, i = t.find(".dropdown-maxItem-alert"), l = n.limitCountErrorMessage; clearTimeout(o.itemLimitAlertTimer), 0 === i.length && (l || (l = "На выбор" + n.limitCount + "个"), i = e('<div class="dropdown-maxItem-alert">' + l + "</div>")), t.append(i), o.itemLimitAlertTimer = setTimeout(function () { t.find(".dropdown-maxItem-alert").remove() }, f) } function a(o) { var n = o || ""; return n = n.replace(/<select[^>]*>/gi, "").replace("</select>", ""), n = n.replace(/<\/optgroup>/gi, ""), n = n.replace(/<optgroup[^>]*>/gi, function (e) { var o = /label="(.[^"]*)"(\s|>)/.exec(e), n = /data\-group\-id="(.[^"]*)"(\s|>)/.exec(e); return '<li class="dropdown-group" data-group-id="' + (n ? n[1] : "") + '">' + (o ? o[1] : "") + "</li>" }), n = n.replace(/<option(.*?)<\/option>/gi, function (o) { var n = e(o).val(), t = />(.*)<\//.exec(o), i = o.indexOf("selected") > -1, l = o.indexOf("disabled") > -1, a = ""; o.replace(/data-(\w+)="?(.[^"]+)"?/g, function (e) { a += e + " " }); return "<li " + (l ? " disabled" : ' tabindex="0"') + ' data-value="' + (n || "") + '" class="dropdown-option ' + (i ? "dropdown-chose" : "") + '" ' + a + ">" + (t ? t[1] : "") + "</li>" }) } function d(o) { var n = this, t = {}, i = "", l = [], a = 0, d = n.config.extendProps; return !(!o || !o.length) && (e.each(o, function (o, n) { var i = n.groupId, s = n.disabled ? " disabled" : "", r = n.selected && !s ? " selected" : "", c = ""; e.each(d, function (e, o) { n[o] && (c += "data-" + o + '="' + n[o] + '" ') }); var p = "<option" + s + r + ' value="' + n.id + '" ' + c + ">" + n.name + "</option>"; r && (l.push('<span class="dropdown-selected">' + n.name + '<i class="del" data-id="' + n.id + '"></i></span>'), a++), i ? t[n.groupId] ? t[n.groupId] += p : t[n.groupId] = n.groupName + "&janking&" + p : t[o] = p }), e.each(t, function (e, o) { var n = o.split("&janking&"); if (2 === n.length) { var t = n[0], l = n[1]; i += '<optgroup label="' + t + '" data-group-id="' + e + '">' + l + "</optgroup>" } else i += o }), [i, l, a]) } function s(o) { function n(o, n) { var t = e(n); this.id = t.prop("value"), this.name = t.text(), this.disabled = t.prop("disabled"), this.selected = t.prop("selected") } var t = o, i = []; return e.each(t.children(), function (o, t) { var l = {}, a = {}, d = e(t); "OPTGROUP" === t.nodeName ? (a.groupId = d.data("groupId"), a.groupName = d.attr("label"), e.each(d.children(), e.proxy(n, l)), e.extend(l, a)) : e.each(d, e.proxy(n, l)), i.push(l) }), i } function r(o, n) { this.$el = e(n), this.$select = this.$el.find("select"), this.placeholder = this.$select.attr("placeholder"), this.config = o, this.name = [], this.isSingleSelect = !this.$select.prop("multiple"), this.selectAmount = 0, this.itemLimitAlertTimer = null, this.isLabelMode = "label" === this.config.multipleMode, this.init() } var c = function () { var e = navigator.userAgent.toLowerCase(); if (e.indexOf("safari") !== -1) return !(e.indexOf("chrome") > -1) }(), p = { readonly: !1, minCount: 0, minCountErrorMessage: "", limitCount: 1 / 0, limitCountErrorMessage: "", input: '<input type="text" maxLength="20" placeholder="Выполните поиск по ключевым словам или идентификатору">', data: [], searchable: !0, searchNoData: '<li style="color:#ddd">Не можете найти никаких данных, попробуйте другое слово /(ㄒoㄒ)/~~</li>', init: o, choice: o, extendProps: [] }, u = { up: 38, down: 40, enter: 13 }, h = { click: "click.iui-dropdown", focus: "focus.iui-dropdown", keydown: "keydown.iui-dropdown", keyup: "keyup.iui-dropdown" }, f = 1e3, m = { show: function (o) { o.stopPropagation(); var n = this; e(document).trigger("click.dropdown"), n.$el.addClass("active") }, search: n(function (o) { var n = this, t = n.config, i = n.$el, l = e(o.target), s = l.val(), r = n.config.data, c = []; o.keyCode > 36 && o.keyCode < 41 || (e.each(r, function (e, o) { (o.groupName && o.groupName.toLowerCase().indexOf(s.toLowerCase()) > -1 || o.name.toLowerCase().indexOf(s.toLowerCase()) > -1 || "" + o.id == "" + s) && c.push(o) }), i.find("ul").html(a(d.call(n, c)[0]) || t.searchNoData)) }, 300), control: function (o) { var n, t, i, l = o.keyCode, a = u, d = 0; l !== a.down && l !== a.up || (n = l === a.up ? -1 : 1, i = this.$el.find("[tabindex]"), t = i.index(e(document.activeElement)), d = t === -1 ? n + 1 ? -1 : 0 : t, d += n, d === i.length && (d = 0), i.eq(d).focus(), o.preventDefault()) }, multiChoose: function (o, n) { var t, a = this, d = a.config, s = a.$select, r = e(o.target), c = r.attr("data-value"), p = r.hasClass("dropdown-chose"), u = []; if (r.hasClass("dropdown-display")) return !1; if (p) r.removeClass("dropdown-chose"), a.selectAmount--; else { if (!(a.selectAmount < d.limitCount)) return l.call(a), !1; r.addClass("dropdown-chose"), a.selectAmount++ } a.name = [], e.each(d.data, function (e, o) { "" + o.id == "" + c && (t = o, o.selected = !p), o.selected && (u.push(o.name), a.name.push('<span class="dropdown-selected">' + o.name + '<i class="del" data-id="' + o.id + '"></i></span>')) }), s.find('option[value="' + c + '"]').prop("selected", !p), p && a.selectAmount < d.minCount && i.call(a), a.$choseList.find(".dropdown-selected").remove(), a.$choseList.prepend(a.name.join("")), a.$el.find(".dropdown-display").attr("title", u.join(",")), d.choice.call(a, o, t) }, singleChoose: function (o) { var n = this, t = n.config, i = n.$el, l = n.$select, a = e(o.target), d = a.attr("data-value"), s = a.hasClass("dropdown-chose"); return !a.hasClass("dropdown-chose") && !a.hasClass("dropdown-display") && (n.name = [], i.removeClass("active").find("li").not(a).removeClass("dropdown-chose"), a.toggleClass("dropdown-chose"), e.each(t.data, function (e, o) { o.selected = !1, "" + o.id == "" + d && (o.selected = s ? 0 : 1, o.selected && n.name.push('<span class="dropdown-selected">' + o.name + '<i class="del" data-id="' + o.id + '"></i></span>')) }), l.find('option[value="' + d + '"]').prop("selected", !0), n.name.push('<span class="placeholder">' + n.placeholder + "</span>"), n.$choseList.html(n.name.join("")), void t.choice.call(n, o)) }, del: function (o) { var n = this, t = n.config, i = e(o.target), l = i.data("id"); return e.each(n.name, function (e, o) { if (o.indexOf('data-id="' + l + '"') !== -1) return n.name.splice(e, 1), !1 }), e.each(n.config.data, function (e, o) { if ("" + o.id == "" + l) return o.selected = !1, !1 }), n.selectAmount--, n.$el.find('[data-value="' + l + '"]').removeClass("dropdown-chose"), n.$el.find('[value="' + l + '"]').prop("selected", !1).removeAttr("selected"), i.closest(".dropdown-selected").remove(), t.choice.call(n, o), !1 }, clearAll: function (o) { var n = this, t = n.config; return o && o.preventDefault(), console.log(this), this.$choseList.find(".del").each(function (o, n) { e(n).trigger("click") }), t.minCount > 0 && i.call(n), this.$el.find(".dropdown-display").removeAttr("title"), !1 } }; r.prototype = { init: function () { var e = this, o = e.config, n = e.$el; e.$select.hide(), n.addClass(e.isSingleSelect ? "dropdown-single" : e.isLabelMode ? "dropdown-multiple-label" : "dropdown-multiple"), 0 === o.data.length && (o.data = s(e.$select)); var t = d.call(e, o.data); e.name = t[1], e.selectAmount = t[2], e.$select.html(t[0]), e.renderSelect(), e.changeStatus(o.disabled ? "disabled" : !!o.readonly && "readonly"), e.config.init() }, renderSelect: function (o, n) { var i, l = this, d = l.$el, s = l.$select, r = a(s.prop("outerHTML")); o ? d.find("ul")[n ? "html" : "append"](r) : (i = t.call(l).replace("{{ul}}", "<ul>" + r + "</ul>"), d.append(i).find("ul").removeAttr("style class")), n && (l.name = [], l.$el.find(".dropdown-selected").remove(), l.$select.val("")), l.$choseList = d.find(".dropdown-chose-list"), l.isLabelMode || l.$choseList.html(e('<span class="placeholder"></span>').text(l.placeholder)), l.$choseList.prepend(l.name ? l.name.join("") : []) }, bindEvent: function () { var o = this, n = o.$el, t = c ? h.click : h.focus; n.on(h.click, function (e) { e.stopPropagation() }), n.on(h.click, ".del", e.proxy(m.del, o)), o.isLabelMode ? (n.on(h.click, ".dropdown-display-label", function () { n.find("input").focus() }), o.config.searchable ? n.on(h.focus, "input", e.proxy(m.show, o)) : n.on(h.click, e.proxy(m.show, o)), n.on(h.keydown, "input", function (e) { 8 === e.keyCode && "" === this.value && o.name.length && n.find(".del").eq(-1).trigger("click") })) : (n.on(t, ".dropdown-display", e.proxy(m.show, o)), n.on(t, ".dropdown-clear-all", e.proxy(m.clearAll, o))), n.on(h.keyup, "input", e.proxy(m.search, o)), n.on(h.keyup, function (n) { var t = n.keyCode, i = u; t === i.enter && e.proxy(o.isSingleSelect ? m.singleChoose : m.multiChoose, o, n)() }), n.on(h.keydown, e.proxy(m.control, o)), n.on(h.click, "li[tabindex]", e.proxy(o.isSingleSelect ? m.singleChoose : m.multiChoose, o)) }, unbindEvent: function () { var e = this, o = e.$el, n = c ? h.click : h.focus; o.off(h.click), o.off(h.click, ".del"), e.isLabelMode ? (o.off(h.click, ".dropdown-display-label"), o.off(h.focus, "input"), o.off(h.keydown, "input")) : (o.off(n, ".dropdown-display"), o.off(n, ".dropdown-clear-all")), o.off(h.keyup, "input"), o.off(h.keyup), o.off(h.keydown), o.off(h.click, "[tabindex]") }, changeStatus: function (e) { var o = this; "readonly" === e ? o.unbindEvent() : "disabled" === e ? (o.$select.prop("disabled", !0), o.unbindEvent()) : (o.$select.prop("disabled", !1), o.bindEvent()) }, update: function (e, o) { var n = this, t = n.config, i = (n.$el, o || !1); if ("[object Array]" === Object.prototype.toString.call(e)) { t.data = i ? e.slice(0) : t.data.concat(e); var l = d.call(n, t.data); n.name = l[1], n.selectAmount = l[2], n.$select.html(l[0]), n.renderSelect(!0, i) } }, destroy: function () { this.unbindEvent(), this.$el.children().not("select").remove(), this.$el.removeClass("dropdown-single dropdown-multiple-label dropdown-multiple"), this.$select.show() }, choose: function (o, n) { var t = "[object Array]" === Object.prototype.toString.call(o) ? o : [o], i = this, l = void 0 === n || !!n; e.each(t, function (e, o) { var t = i.$el.find('[data-value="' + o + '"]'), a = t.hasClass("dropdown-chose"); a !== l && t.trigger(h.click, n || !0) }) }, reset: function () { m.clearAll.call(this) } }, e(document).on("click.dropdown", function () { e(".dropdown-single,.dropdown-multiple,.dropdown-multiple-label").removeClass("active") }), e.fn.dropdown = function (o) { return this.each(function (n, t) { e(t).data("dropdown", new r(e.extend(!0, {}, p, o), t)) }), this } })(jQuery);
\ No newline at end of file
diff --git a/views/header.erb b/views/header.erb
index edf08b8..87e89f5 100644
--- a/views/header.erb
+++ b/views/header.erb
@@ -7,6 +7,7 @@
     <title><%= @page_name %></title>
     <link rel="stylesheet" href="/assets/bootstrap/css/bootstrap.min.css">
     <link rel="stylesheet" href="/assets/css/Footer-Dark-icons.css">
+    <link rel="stylesheet" href="/js/jquery.dropdown.min.css">
     <script src="/js/jquery-3.7.1.min.js"></script>
 </head>
 
@@ -20,6 +21,10 @@
     </div>
     <div class="container">
         <div class="hstack gap-3">
+            <span class="p-1">
+                <a href="/">главная</a>
+            </span>
+            <span>|</span>
             <span class="p-1">
                 <a href="/repos">git-репозитории</a>
             </span>
diff --git a/views/rcpcrt.erb b/views/rcpcrt.erb
index 4240a5d..4e16e47 100644
--- a/views/rcpcrt.erb
+++ b/views/rcpcrt.erb
@@ -9,6 +9,7 @@
             toolbar: "search, go_to_line, fullscreen, |, undo, redo, |, select_font,|, highlight, reset_highlight, word_wrap, |, syntax_selection"
         });
     </script>
+    <script src="/js/jquery.dropdown.min.js"></script>
     <% unless @error_data.nil? %>
     <div class="container">
         <div class="alert alert-warning alert-dismissible fade show" role="alert"><span><%= @error_data %></span><button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Закрыть"></button></div>
@@ -18,19 +19,38 @@
         <form action="/rcpcreate" method="post">
             <div class="mb-3">
                 <label for="filepath" class="form-label">Имя рецепта (англиские буквы, _, .)</label>
-                <input type="email" class="form-control" id="filepath" name="filepath">
+                <input type="text" class="form-control" id="filepath" name="filepath" value="<%= @old_filepath %>">
             </div>
             <div class="mb-3">
                 <label for="description" class="form-label">Описание рецепта сборки</label>
-                <textarea class="form-control" id="description" name="description" rows="3"></textarea>
+                <textarea class="form-control" id="description" name="description" rows="3"><%= @old_description %></textarea>
             </div>
             <div class="mb-3">
                 <label for="codedata" class="form-label">Код</label>
-                <textarea class="form-control" id="codedata" name="codedata" rows="3"></textarea>
+                <textarea class="form-control" id="codedata" name="codedata" rows="3"><%= @old_codedata %></textarea>
+            </div>
+            <div class="mb-3">
+                <label for="gitlist" class="form-label">git проекты, использующие рецепт</label>
+                <div class="gitlist">
+                    <select class="form-control" id="gitlst" name="gitlst[]" multiple>
+                    <% @repo_data.each do |item| %>
+                        <% if !@old_gitlst.nil? && @old_gitlst.include?(item[:id].to_s) %>
+                            <option value="<%= item[:id] %>" selected><%= item[:reponame] %></option>
+                        <% else %>
+                            <option value="<%= item[:id] %>"><%= item[:reponame] %></option>
+                        <% end %>
+                    <% end %>
+                    </select>
+                </div>
             </div>
             <div class="mb-3 text-center">
                 <button type="submit" class="btn btn-primary">Сохранить</button>
             </div>
         </form>
     </div>
+    <script>
+        $('.gitlist').dropdown({
+            searchNoData: '<li style="color:#ddd">Нет данных</li>',
+        });
+    </script>
 <%= erb :footer %>
\ No newline at end of file
diff --git a/views/rcpedit.erb b/views/rcpedit.erb
new file mode 100644
index 0000000..7a2e480
--- /dev/null
+++ b/views/rcpedit.erb
@@ -0,0 +1,125 @@
+<%= erb :header %>
+    <script src="/js/edit_area_full.js"></script>
+    <script language="javascript" type="text/javascript">
+        editAreaLoader.init({
+            id: "codedata",
+            syntax: "bash",
+            start_highlight: true,
+            language: "ru",
+            toolbar: "search, go_to_line, fullscreen, |, undo, redo, |, select_font,|, highlight, reset_highlight, word_wrap, |, syntax_selection"
+        });
+    </script>
+    <script src="/js/jquery.dropdown.min.js"></script>
+    <% unless @error_data.nil? %>
+    <div class="container">
+        <div class="alert alert-warning alert-dismissible fade show" role="alert"><span><%= @error_data %></span><button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Закрыть"></button></div>
+    </div>
+    <% end %>
+    <div class="container">
+        <form action="/recips/<%= ERB::Util.url_encode(@rcp_id) %>" method="post">
+            <div class="mb-3">
+                <label for="filepath" class="form-label">Имя рецепта (англиские буквы, _, .)</label>
+                <input type="text" class="form-control" id="filepath" name="filepath" value="<%= @old_filepath %>">
+            </div>
+            <div class="mb-3">
+                <label for="description" class="form-label">Описание рецепта сборки</label>
+                <textarea class="form-control" id="description" name="description" rows="3"><%= @old_description %></textarea>
+            </div>
+            <div class="mb-3">
+                <label for="codedata" class="form-label">Код</label>
+                <textarea class="form-control" id="codedata" name="codedata" rows="3"><%= @old_codedata %></textarea>
+            </div>
+            <div class="mb-3">
+                <label for="gitlist" class="form-label">git проекты, использующие рецепт</label>
+                <div class="gitlist">
+                    <select class="form-control" id="gitlst" name="gitlst[]" multiple>
+                    <% @repo_data.each do |item| %>
+                        <% if !@old_gitlst.nil? && @old_gitlst.include?(item[:id].to_s) %>
+                            <option value="<%= item[:id] %>" selected><%= item[:reponame] %></option>
+                        <% else %>
+                            <option value="<%= item[:id] %>"><%= item[:reponame] %></option>
+                        <% end %>
+                    <% end %>
+                    </select>
+                </div>
+            </div>
+            <div class="mb-3 text-center">
+                <button type="submit" class="btn btn-primary">Сохранить</button>
+                <button type="submit" class="btn btn-danger" id="delete">Удалить</button>
+                <div id="winkeeper"></div>
+            </div>
+        </form>
+    </div>
+    <script>
+        $('.gitlist').dropdown({
+            searchNoData: '<li style="color:#ddd">Нет данных</li>',
+        });
+    </script>
+    <script src="/js/jquery-confirm.min.js"></script>
+    <script>
+        $("#delete").confirm({
+            title: 'Подтвердите удаление репозитория!',
+            content: '' +
+            '<div class="container">' +
+            '<form action="/rcpdelete/<%= ERB::Util.url_encode(@rcp_id) %>" class="formName" method="post">' +
+            '<div class="text-danger mx-auto p-2">' +
+            '<label>Введите название удаляемого рецепта</label>' +
+            '<input type="text" class="frmchk form-control" required name="rcpnamedup"/>' +
+            '<input type="hidden" class="frmchk form-control" id="rcphid" name="rcphid" value="<%= @rcp_name %>"/>' +
+            '</div>' +
+            '</form>' +
+            '</div>',
+            container: '#winkeeper',
+            theme: 'bootstrap',
+            buttons: {
+                formSubmit: {
+                    text: 'Удалить',
+                    titleClass: 'text-danger mx-auto p-2',
+                    btnClass: 'btn btn-danger',
+                    action: function () {
+                        var correct_name = this.$content.find("#rcphid").val();
+                        var name = this.$content.find('.frmchk').val();
+                        if(!name){
+                            $.alert({
+                                title: 'Предупреждение!',
+                                content: 'Название не может быть пустым',
+                                container: '#winkeeper',
+                                theme: 'bootstrap',
+                                buttons: {
+                                    ok: {
+                                        text: 'Хорошо',
+                                        btnClass: 'btn btn-danger',
+                                    }
+                                }
+                            });
+                            return false;
+                        }
+                        if (name != correct_name){
+                            $.alert({
+                                title: 'Предупреждение!',
+                                content: 'Название задано неверно',
+                                container: '#winkeeper',
+                                theme: 'bootstrap',
+                                buttons: {
+                                    ok: {
+                                        text: 'Хорошо',
+                                        btnClass: 'btn btn-danger',
+                                    }
+                                }
+                            });
+                            return false;
+                        }
+                        this.$content.find('form').submit();
+                        return true;
+                    }
+                },
+                cancel:  {
+                    text: 'Отменить',
+                    btnClass: 'btn btn-primary',
+                    action: function () {
+                    //close
+                    }},
+            },
+        });
+    </script>
+<%= erb :footer %>
\ No newline at end of file
diff --git a/views/receips.erb b/views/receips.erb
index c2d7b0f..a0b0c00 100644
--- a/views/receips.erb
+++ b/views/receips.erb
@@ -1,16 +1,19 @@
 <%= erb :header %>
     <div class="container py-4 py-xl-5">
-        <div class="row mb-5">
+        <div class="row pb-5">
             <div class="col-md-8 col-xl-6 text-center mx-auto">
                 <h2>Доступные рецепты</h2>
                 <p class="w-lg-50">Страница управления рецептами</p>
                 <div>
-                    <div class="px-3"><a href="/rcpcreate"><svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16" class="bi bi-plus-circle text-primary" style="font-size: 29px;">
-                                <path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"></path>
-                                <path d="M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3A.5.5 0 0 1 8 4z"></path>
-                            </svg>&nbsp;Добавить рецепт</a></div>
+                    <div class="px-3"><a href="/rcpcreate">
+                        <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16" class="bi bi-plus-circle text-primary" style="font-size: 29px;">
+                            <path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"></path>
+                            <path d="M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3A.5.5 0 0 1 8 4z"></path>
+                        </svg>&nbsp;Добавить рецепт</a>
+                    </div>
                 </div>
             </div>
+        </div>
         <div class="container text-center">
             <div class="row gy-3">
                 <% @rcp_data.each do |item| %>