Repository: glushchenko/fsnotes
Branch: master
Commit: 866f59188866
Files: 487
Total size: 5.7 MB
Directory structure:
gitextract_5ehxlhed/
├── .gitattributes
├── .github/
│ └── ISSUE_TEMPLATE/
│ └── bug_report.yml
├── .gitignore
├── .swiftlint.yml
├── .travis.yml
├── CODE_OF_CONDUCT.md
├── FSNotes/
│ ├── .bartycrouch.toml
│ ├── AboutViewController.swift
│ ├── AboutWindowController.swift
│ ├── AppDelegate+URLRoutes.swift
│ ├── AppDelegate.swift
│ ├── Base.lproj/
│ │ └── Main.storyboard
│ ├── EditorViewController+ScrollPosition.swift
│ ├── EditorViewController+Sharing.swift
│ ├── EditorViewController.swift
│ ├── Extensions/
│ │ ├── NSAppearance+.swift
│ │ ├── NSColor+.swift
│ │ ├── NSFont+.swift
│ │ ├── NSImage+.swift
│ │ ├── NSWindow+.swift
│ │ └── UserDefaultsManagement+.swift
│ ├── FSNotes (CloudKit).entitlements
│ ├── FSNotes.entitlements
│ ├── Helpers/
│ │ ├── FSNTextAttachmentCell.swift
│ │ ├── FileSystemEventManager.swift
│ │ ├── FileWatcher.swift
│ │ ├── FileWatcherEvent.swift
│ │ ├── Printer.swift
│ │ ├── PrinterLegacy.swift
│ │ ├── SandboxBookmark.swift
│ │ ├── Sidebar.swift
│ │ └── UserDataService.swift
│ ├── Images.xcassets/
│ │ ├── AppIcon.appiconset/
│ │ │ └── Contents.json
│ │ ├── Contents.json
│ │ ├── Icons/
│ │ │ ├── AppIconClassic.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── AppIconModern.imageset/
│ │ │ │ └── Contents.json
│ │ │ └── Contents.json
│ │ ├── checkbox_empty.imageset/
│ │ │ └── Contents.json
│ │ ├── checkbox_flipped.imageset/
│ │ │ └── Contents.json
│ │ ├── checkbox_new.imageset/
│ │ │ └── Contents.json
│ │ ├── code.colorset/
│ │ │ └── Contents.json
│ │ ├── colors_background/
│ │ │ ├── Contents.json
│ │ │ ├── background_tag.colorset/
│ │ │ │ └── Contents.json
│ │ │ └── background_win.colorset/
│ │ │ └── Contents.json
│ │ ├── copy.png.imageset/
│ │ │ └── Contents.json
│ │ ├── divider.colorset/
│ │ │ └── Contents.json
│ │ ├── dockIcon2.imageset/
│ │ │ └── Contents.json
│ │ ├── dockIcon4.imageset/
│ │ │ └── Contents.json
│ │ ├── friend.imageset/
│ │ │ └── Contents.json
│ │ ├── highlight.colorset/
│ │ │ └── Contents.json
│ │ ├── link.colorset/
│ │ │ └── Contents.json
│ │ ├── locked.imageset/
│ │ │ └── Contents.json
│ │ ├── mainBackground.colorset/
│ │ │ └── Contents.json
│ │ ├── mainText.colorset/
│ │ │ └── Contents.json
│ │ ├── menuBar.imageset/
│ │ │ └── Contents.json
│ │ ├── new_note_button.imageset/
│ │ │ └── Contents.json
│ │ ├── pin.imageset/
│ │ │ └── Contents.json
│ │ ├── prefsAdvanced.imageset/
│ │ │ └── Contents.json
│ │ ├── prefsEditor.imageset/
│ │ │ └── Contents.json
│ │ ├── prefsGeneral.imageset/
│ │ │ └── Contents.json
│ │ ├── prefsGit.imageset/
│ │ │ └── Contents.json
│ │ ├── prefsLayout.imageset/
│ │ │ └── Contents.json
│ │ ├── prefsWeb.imageset/
│ │ │ └── Contents.json
│ │ ├── privacy.imageset/
│ │ │ └── Contents.json
│ │ ├── quoteColor.colorset/
│ │ │ └── Contents.json
│ │ ├── reverseBackground.colorset/
│ │ │ └── Contents.json
│ │ ├── sidebar_archive.imageset/
│ │ │ └── Contents.json
│ │ ├── sidebar_external.imageset/
│ │ │ └── Contents.json
│ │ ├── sidebar_icloud_drive.imageset/
│ │ │ └── Contents.json
│ │ ├── sidebar_inbox.imageset/
│ │ │ └── Contents.json
│ │ ├── sidebar_notes.imageset/
│ │ │ └── Contents.json
│ │ ├── sidebar_project.imageset/
│ │ │ └── Contents.json
│ │ ├── sidebar_project_encrypted_locked.imageset/
│ │ │ └── Contents.json
│ │ ├── sidebar_project_encrypted_unlocked.imageset/
│ │ │ └── Contents.json
│ │ ├── sidebar_tag.imageset/
│ │ │ └── Contents.json
│ │ ├── sidebar_todo.imageset/
│ │ │ └── Contents.json
│ │ ├── sidebar_trash.imageset/
│ │ │ └── Contents.json
│ │ ├── sidebar_untagged.imageset/
│ │ │ └── Contents.json
│ │ └── web.imageset/
│ │ └── Contents.json
│ ├── Info.plist
│ ├── LayoutManager.swift
│ ├── Localizable.xcstrings
│ ├── MainWindow.swift
│ ├── MainWindowController.swift
│ ├── Model/
│ │ ├── StorageEntity+CoreDataClass.swift
│ │ └── StorageEntity+CoreDataProperties.swift
│ ├── NSWindowController+.swift
│ ├── NoteViewController.swift
│ ├── Preferences/
│ │ ├── MasterPasswordViewController.swift
│ │ ├── PreferencesAdvancedViewController.swift
│ │ ├── PreferencesEditorViewController.swift
│ │ ├── PreferencesGeneralViewController.swift
│ │ ├── PreferencesGitViewController.swift
│ │ ├── PreferencesSecurityViewController.swift
│ │ ├── PreferencesUserInterfaceViewController.swift
│ │ ├── PreferencesWebViewController.swift
│ │ └── SettingsViewController.swift
│ ├── PrefsViewController.swift
│ ├── PrefsWindowController.swift
│ ├── ProjectSettingsViewController.swift
│ ├── SidebarScrollView.swift
│ ├── View/
│ │ ├── AboutImageView.swift
│ │ ├── ClickableTextField.swift
│ │ ├── EditTextView+Clicked.swift
│ │ ├── EditTextView+Complete.swift
│ │ ├── EditTextView+DragOperation.swift
│ │ ├── EditTextView+MoveLines.swift
│ │ ├── EditTextView+Todo.swift
│ │ ├── EditTextView.swift
│ │ ├── EditorScrollView.swift
│ │ ├── EditorSplitView.swift
│ │ ├── EditorView.swift
│ │ ├── HyperlinkTextField.swift
│ │ ├── MPreviewContainerView.swift
│ │ ├── MPreviewFindPanel.swift
│ │ ├── NameTextField.swift
│ │ ├── NoteCellView.swift
│ │ ├── NoteRowView.swift
│ │ ├── NotesCounterView.swift
│ │ ├── NotesTableView.swift
│ │ ├── OutlineHeaderView.swift
│ │ ├── PreviewTextField.swift
│ │ ├── SearchTextField.swift
│ │ ├── SidebarCellView.swift
│ │ ├── SidebarHeaderCellView.swift
│ │ ├── SidebarNotesView.swift
│ │ ├── SidebarOutlineView.swift
│ │ ├── SidebarSplitView.swift
│ │ ├── SidebarTableRowView.swift
│ │ ├── TitleBarView.swift
│ │ ├── TitleTextField.swift
│ │ └── VerticallyAlignedTextFieldCell.swift
│ ├── ViewController+Git.swift
│ ├── ViewController+Menu.swift
│ ├── ViewController+Print.swift
│ ├── ViewController+Web.swift
│ ├── ViewController.swift
│ ├── bin/
│ │ └── git
│ ├── modern.icon/
│ │ └── icon.json
│ └── mul.lproj/
│ └── Main.xcstrings
├── FSNotes Info (Notarized).plist
├── FSNotes iOS/
│ ├── .bartycrouch.toml
│ ├── AppDelegate.swift
│ ├── Assets.xcassets/
│ │ ├── Colors/
│ │ │ ├── Contents.json
│ │ │ └── fsColor.colorset/
│ │ │ └── Contents.json
│ │ ├── Contents.json
│ │ ├── Editor/
│ │ │ ├── Contents.json
│ │ │ ├── checkbox.imageset/
│ │ │ │ └── Contents.json
│ │ │ └── checkbox_empty.imageset/
│ │ │ └── Contents.json
│ │ ├── Icons/
│ │ │ ├── AppIconClassic-2025.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── AppIconModern.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── AppIconNy-2026.imageset/
│ │ │ │ └── Contents.json
│ │ │ └── Contents.json
│ │ ├── LaunchScreenImage.imageset/
│ │ │ └── Contents.json
│ │ ├── Sidebar/
│ │ │ ├── Contents.json
│ │ │ ├── sidebar_archive.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── sidebar_inbox.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── sidebar_notes.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── sidebar_project.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── sidebar_project_encrypted_locked.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── sidebar_project_encrypted_unlocked.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── sidebar_tag.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── sidebar_todo.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── sidebar_trash.imageset/
│ │ │ │ └── Contents.json
│ │ │ └── sidebar_untagged.imageset/
│ │ │ └── Contents.json
│ │ ├── Sidebar Actions/
│ │ │ ├── Contents.json
│ │ │ └── gitSettings.imageset/
│ │ │ └── Contents.json
│ │ ├── Toolbar/
│ │ │ ├── Contents.json
│ │ │ ├── codeBlockAsset.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── numbered_list.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── ordered_list.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── pictureAsset.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── quote.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── redo.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── toolbarBold.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── toolbarHeader.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── toolbarImage.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── toolbarIndentLeft.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── toolbarIndentRight.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── toolbarItalic.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── toolbarTag.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── toolbarTodo.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── toolbarWiki.imageset/
│ │ │ │ └── Contents.json
│ │ │ └── undo.imageset/
│ │ │ └── Contents.json
│ │ └── Touch Bar/
│ │ ├── Contents.json
│ │ ├── Image.imageset/
│ │ │ └── Contents.json
│ │ ├── bold.imageset/
│ │ │ └── Contents.json
│ │ ├── codeblock.imageset/
│ │ │ └── Contents.json
│ │ ├── indent.imageset/
│ │ │ └── Contents.json
│ │ ├── italic.imageset/
│ │ │ └── Contents.json
│ │ ├── tb_link.imageset/
│ │ │ └── Contents.json
│ │ ├── todo.imageset/
│ │ │ └── Contents.json
│ │ └── unindent.imageset/
│ │ └── Contents.json
│ ├── DatePickerViewController.swift
│ ├── EditorViewController+QuickLook.swift
│ ├── EditorViewController+Search.swift
│ ├── EditorViewController.swift
│ ├── Extensions/
│ │ ├── UIApplication+.swift
│ │ ├── UIBarButtonItem+.swift
│ │ ├── UIColor+.swift
│ │ ├── UIFont+.swift
│ │ ├── UIImage+.swift
│ │ ├── UITextView+.swift
│ │ └── UserDefaultsManagement+.swift
│ ├── FSNotes iOS.entitlements
│ ├── FSNotes_iOS.xcdatamodeld/
│ │ ├── .xccurrentversion
│ │ └── FSNotes_iOS.xcdatamodel/
│ │ └── contents
│ ├── Helpers/
│ │ ├── Buttons.swift
│ │ ├── CloudDriveManager.swift
│ │ ├── FolderPopoverActions.swift
│ │ ├── SandboxBookmark.swift
│ │ ├── ShortcutIdentifier.swift
│ │ ├── Sidebar.swift
│ │ ├── SingleImageTouchDownGestureRecognizer.swift
│ │ └── SingleTouchDownGestureRecognizer.swift
│ ├── Icons/
│ │ ├── classic-2025.icon/
│ │ │ └── icon.json
│ │ ├── modern.icon/
│ │ │ └── icon.json
│ │ └── ny-2026.icon/
│ │ └── icon.json
│ ├── ImagePreviewViewController.swift
│ ├── Info.plist
│ ├── InfoPlist.xcstrings
│ ├── Launch Screen.storyboard
│ ├── LaunchImage.launchimage/
│ │ └── Contents.json
│ ├── Localizable.xcstrings
│ ├── Main.storyboard
│ ├── MainNavigationController.swift
│ ├── MoveViewController.swift
│ ├── Preferences/
│ │ ├── AppIconViewController.swift
│ │ ├── CodeFontViewController.swift
│ │ ├── CodeThemeViewController.swift
│ │ ├── DefaultExtensionControllerView.swift
│ │ ├── ExternalViewController.swift
│ │ ├── FontViewController.swift
│ │ ├── GitTableViewCell.swift
│ │ ├── GitViewController.swift
│ │ ├── LanguageViewController.swift
│ │ ├── ProViewController.swift
│ │ ├── ProjectSettingsViewController.swift
│ │ ├── ProjectsViewController.swift
│ │ ├── SecurityViewController.swift
│ │ ├── SettingsEditorViewController.swift
│ │ ├── SettingsTableViewCell.swift
│ │ ├── SettingsViewController.swift
│ │ ├── SidebarViewController.swift
│ │ ├── SortByViewController.swift
│ │ └── ThanksViewController.swift
│ ├── RevisionsViewController.swift
│ ├── SceneDelegate.swift
│ ├── View/
│ │ ├── EditTextView.swift
│ │ ├── EditorSelectionRect.swift
│ │ ├── ImageScrollView.swift
│ │ ├── NoteCellView.swift
│ │ ├── NotesTableView.swift
│ │ ├── SidebarTableCellView.swift
│ │ └── SidebarTableView.swift
│ ├── ViewController+More.swift
│ ├── ViewController.swift
│ ├── fr.lproj/
│ │ └── Main.storyboard
│ ├── nl-NL.lproj/
│ │ └── Main.storyboard
│ ├── pt-PT.lproj/
│ │ └── Main.storyboard
│ ├── ru.lproj/
│ │ ├── InfoPlist.strings
│ │ ├── LaunchScreen.strings
│ │ ├── Localizable.strings
│ │ └── Main.storyboard
│ └── uk.lproj/
│ └── Main.storyboard
├── FSNotes iOS Share/
│ ├── .bartycrouch.toml
│ ├── FSNotes iOS Share.entitlements
│ ├── Info.plist
│ ├── Localizable.xcstrings
│ ├── MainInterface.storyboard
│ ├── NSMutableAttributedString+.swift
│ ├── ShareViewController.swift
│ ├── es.lproj/
│ │ └── Localizable.strings
│ ├── pt.lproj/
│ │ └── InfoPlist.strings
│ ├── ru.lproj/
│ │ ├── InfoPlist.strings
│ │ ├── Localizable.strings
│ │ └── MainInterface.strings
│ ├── uk.lproj/
│ │ ├── InfoPlist.strings
│ │ └── MainInterface.strings
│ ├── zh-Hans-CN.lproj/
│ │ ├── InfoPlist.strings
│ │ └── Localizable.strings
│ └── zh-Hans.lproj/
│ └── MainInterface.strings
├── FSNotes.xcodeproj/
│ ├── project.pbxproj
│ ├── project.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ ├── IDEWorkspaceChecks.plist
│ │ ├── WorkspaceSettings.xcsettings
│ │ └── swiftpm/
│ │ └── Package.resolved
│ └── xcshareddata/
│ └── xcschemes/
│ ├── FSNotes (iCloud).xcscheme
│ ├── FSNotes iOS Share Extension.xcscheme
│ ├── FSNotes iOS.xcscheme
│ └── FSNotes.xcscheme
├── FSNotes.xcworkspace/
│ └── contents.xcworkspacedata
├── FSNotesCore/
│ ├── Business/
│ │ ├── ApiResponse.swift
│ │ ├── AppearanceType.swift
│ │ ├── AttributedBox.swift
│ │ ├── FSTag.swift
│ │ ├── ImageFormat.swift
│ │ ├── LanguageType.swift
│ │ ├── Markdown.swift
│ │ ├── Note+Preview.swift
│ │ ├── Note.swift
│ │ ├── NoteAttachment.swift
│ │ ├── NoteContainer.swift
│ │ ├── NoteType.swift
│ │ ├── PreviewState.swift
│ │ ├── ProgressState.swift
│ │ ├── Project+Date.swift
│ │ ├── Project.swift
│ │ ├── ProjectSettings.swift
│ │ ├── RuntimeError.swift
│ │ ├── SearchQuery.swift
│ │ ├── SettingsFilesNaming.swift
│ │ ├── SidebarItem.swift
│ │ ├── SidebarItemType.swift
│ │ ├── SortBy.swift
│ │ ├── SortDirection.swift
│ │ ├── Storage.swift
│ │ ├── StorageType.swift
│ │ ├── TextBundleInfo.swift
│ │ └── UndoData.swift
│ ├── CodeBlockDetector.swift
│ ├── Core macOS/
│ │ └── zh-Hans-CN.lproj/
│ │ └── InfoPlist.strings
│ ├── Extensions/
│ │ ├── Data+.swift
│ │ ├── Date+.swift
│ │ ├── DateFormatter+.swift
│ │ ├── FileManager+.swift
│ │ ├── NSAttributedString+.swift
│ │ ├── NSAttributedStringKey+.swift
│ │ ├── NSMutableAttributedString+.swift
│ │ ├── NSRange+.swift
│ │ ├── NSTextCheckingResult+.swift
│ │ ├── Pasteboard.swift
│ │ ├── Project+Git.swift
│ │ ├── Storage+Git.swift
│ │ ├── String+.swift
│ │ ├── String+Punycode.swift
│ │ ├── URL+.swift
│ │ ├── URL+Image.swift
│ │ └── UTI.swift
│ ├── FSParser.swift
│ ├── Git/
│ │ ├── authentication/
│ │ │ ├── Authentication.swift
│ │ │ ├── KeyAuthentication.swift
│ │ │ └── PasswordAuthentication.swift
│ │ ├── branch/
│ │ │ ├── Branch.swift
│ │ │ ├── Branches.swift
│ │ │ └── BranchesIterator.swift
│ │ ├── commit/
│ │ │ └── Commit.swift
│ │ ├── commons/
│ │ │ ├── Blob.swift
│ │ │ ├── ConfigManager.swift
│ │ │ ├── Error.swift
│ │ │ ├── Errors.swift
│ │ │ ├── OID.swift
│ │ │ ├── Object.swift
│ │ │ ├── Progress.swift
│ │ │ ├── Signature.swift
│ │ │ ├── StaticSshKeyDelegate.swift
│ │ │ ├── Strings.swift
│ │ │ └── Wrapper.swift
│ │ ├── diff/
│ │ │ ├── Diff.swift
│ │ │ └── DiffEntry.swift
│ │ ├── head/
│ │ │ ├── Head+Checkout.swift
│ │ │ ├── Head+Merge.swift
│ │ │ └── Head.swift
│ │ ├── index/
│ │ │ ├── Index+Commit.swift
│ │ │ ├── Index+Files.swift
│ │ │ └── Index.swift
│ │ ├── reference/
│ │ │ ├── Reference+Target.swift
│ │ │ └── Reference.swift
│ │ ├── remote/
│ │ │ ├── Remote.swift
│ │ │ └── Remotes.swift
│ │ ├── repository/
│ │ │ ├── Repository+Commit.swift
│ │ │ ├── Repository+Lookup.swift
│ │ │ ├── Repository+Open.swift
│ │ │ ├── Repository.swift
│ │ │ └── RepositoryManager.swift
│ │ ├── revision/
│ │ │ ├── FileHistoryIterator.swift
│ │ │ └── RevisionIterator.swift
│ │ ├── status/
│ │ │ ├── Status.swift
│ │ │ ├── StatusIterator.swift
│ │ │ └── Statuses.swift
│ │ ├── tag/
│ │ │ ├── Tag.swift
│ │ │ ├── TagIterator.swift
│ │ │ └── Tags.swift
│ │ └── tree/
│ │ ├── Tree.swift
│ │ └── TreeEntry.swift
│ ├── HtmlExtractor.swift
│ ├── ImagesProcessor.swift
│ ├── KeychainConfiguration.swift
│ ├── KeychainPasswordItem.swift
│ ├── MPreviewView.swift
│ ├── NSTextAttachment+.swift
│ ├── NSTextStorage++.swift
│ ├── NameHelper.swift
│ ├── Note+History.swift
│ ├── NoteCellView+.swift
│ ├── NoteMeta.swift
│ ├── NotesTextProcessor.swift
│ ├── RepositoryAction.swift
│ ├── SwiftHighlighter/
│ │ ├── Languages/
│ │ │ ├── Assembly.swift
│ │ │ ├── Bash.swift
│ │ │ ├── C.swift
│ │ │ ├── Clojure.swift
│ │ │ ├── Cpp.swift
│ │ │ ├── Csharp.swift
│ │ │ ├── Css.swift
│ │ │ ├── Dart.swift
│ │ │ ├── Erlang.swift
│ │ │ ├── Go.swift
│ │ │ ├── Groovy.swift
│ │ │ ├── Haskell.swift
│ │ │ ├── Html.swift
│ │ │ ├── Java.swift
│ │ │ ├── JavaScript.swift
│ │ │ ├── Kotlin.swift
│ │ │ ├── Lisp.swift
│ │ │ ├── Lua.swift
│ │ │ ├── Matlab.swift
│ │ │ ├── Mermaid.swift
│ │ │ ├── ObjectiveC.swift
│ │ │ ├── Perl.swift
│ │ │ ├── Php.swift
│ │ │ ├── Python.swift
│ │ │ ├── R.swift
│ │ │ ├── Ruby.swift
│ │ │ ├── Rust.swift
│ │ │ ├── Scala.swift
│ │ │ ├── Scratch.swift
│ │ │ ├── Shell.swift
│ │ │ ├── Sql.swift
│ │ │ ├── Swift.swift
│ │ │ ├── TypeScript.swift
│ │ │ └── Vb.swift
│ │ ├── Platform.swift
│ │ ├── SwiftHighlighter.swift
│ │ ├── Theme.swift
│ │ └── Themes/
│ │ ├── AtomOneDark.swift
│ │ ├── AtomOneLight.swift
│ │ ├── GitHubDark.swift
│ │ ├── GitHubLight.swift
│ │ ├── SolarizedDark.swift
│ │ └── SolarizedLight.swift
│ ├── TextFormatter.swift
│ ├── TextStorageProcessor.swift
│ ├── UserDefaultsManagement.swift
│ └── ViewController+WebApi.swift
├── LICENSE
├── Logo/
│ └── License
├── Podfile
├── README.md
├── README_zh_CN.md
├── README_zh_TW.md
└── Resources/
├── Icons/
│ ├── EncryptedTextPack.icns
│ ├── Markdown.icns
│ ├── Text.icns
│ └── TextBundle.icns
├── Initial/
│ ├── FSNotes - Readme.md
│ ├── FSNotes 4.0 Change Log.textbundle/
│ │ ├── info.json
│ │ └── text.markdown
│ ├── FSNotes 4.0 for iOS.textbundle/
│ │ ├── info.json
│ │ └── text.markdown
│ ├── FSNotes 5.0 Change Log.textbundle/
│ │ ├── info.json
│ │ └── text.md
│ ├── Meet FSNotes 6.textbundle/
│ │ ├── info.json
│ │ └── text.markdown
│ └── Meet FSNotes 7.textbundle/
│ ├── info.json
│ └── text.markdown
├── MPreview.bundle/
│ ├── index.html
│ ├── js/
│ │ └── tex-mml-chtml.js
│ └── main.css
└── Welcome.bundle/
├── 1. Introduction.textbundle/
│ ├── info.json
│ └── text.markdown
├── 2. Links.textbundle/
│ ├── info.json
│ └── text.markdown
├── 3. Shortcuts.textbundle/
│ ├── info.json
│ └── text.markdown
├── 4. Sidebar.textbundle/
│ ├── info.json
│ └── text.markdown
├── 5. Tags and subtags.textbundle/
│ ├── info.json
│ └── text.markdown
├── 6. Mermaid and MathJax.textbundle/
│ ├── info.json
│ └── text.markdown
├── 7. Git powered versioning.textbundle/
│ ├── info.json
│ └── text.markdown
├── 8. Containers.textbundle/
│ ├── info.json
│ └── text.markdown
└── 9. GFM Markdown.textbundle/
├── info.json
└── text.markdown
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitattributes
================================================
*.pbxproj merge=union
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.yml
================================================
name: Bug report
description: Create a report to help us improve
labels: 'bug'
body:
- type: textarea
attributes:
label: Description
description: >-
A clear and concise description of what the bug is.
validations:
required: true
- type: textarea
attributes:
label: To Reproduce
description: >-
Steps to reproduce the behavior.
value: |
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
validations:
required: true
- type: textarea
attributes:
label: Expected behavior
description: >-
A clear and concise description of what you expected to happen.
- type: input
attributes:
label: FSNotes version
validations:
required: true
- type: input
attributes:
label: macOS/iOS version
validations:
required: true
- type: textarea
attributes:
label: Additional context
description: >-
Add any other context about the problem here.
================================================
FILE: .gitignore
================================================
Pods
*.xcuserstate
xcuserdata
Podfile.lock
FSNotes.xcworkspace/xcshareddata/*
FSNotes.xcworkspace/xcuserdata/*
FSNotes.xcodeproj/xcuserdata/*
================================================
FILE: .swiftlint.yml
================================================
included: # paths to include during linting. `--path` is ignored if present.
- FSNotesCore
excluded: # paths to ignore during linting. Takes precedence over `included`.
- Pods
line_length:
warning: 220
disabled_rules:
- implicit_getter
- identifier_name
cyclomatic_complexity: 20
function_body_length: 100
file_length: 1000
================================================
FILE: .travis.yml
================================================
language: swift
os: osx
osx_image: xcode11.5
xcode_workspace: FSNotes.xcworkspace
before_install:
- pod install --repo-update
env:
- SCHEME=FSNotes SDK=macosx
- SCHEME="FSNotes iOS" SDK=iphonesimulator
script: xcodebuild -workspace FSNotes.xcworkspace -scheme "$SCHEME" build -sdk $SDK ONLY_ACTIVE_ARCH=NO -UseModernBuildSystem=NO -quiet
branches:
only: [master]
================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at fluder (at) icloud (dot) com. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq
================================================
FILE: FSNotes/.bartycrouch.toml
================================================
[update]
tasks = ["interfaces", "code", "transform", "normalize"]
[update.interfaces]
paths = ["."]
defaultToBase = true
ignoreEmptyStrings = false
unstripped = false
[update.code]
codePaths = ["."]
localizablePaths = ["."]
defaultToKeys = true
additive = true
unstripped = false
plistArguments = true
[update.transform]
codePaths = ["."]
localizablePaths = ["."]
transformer = "foundation"
supportedLanguageEnumPath = "."
typeName = "BartyCrouch"
translateMethodName = "translate"
[update.normalize]
paths = ["."]
sourceLocale = "en"
harmonizeWithSource = true
sortByKeys = true
[lint]
paths = ["."]
duplicateKeys = false
emptyValues = true
================================================
FILE: FSNotes/AboutViewController.swift
================================================
//
// AboutViewController.swift
// FSNotes
//
// Created by Олександр Глущенко on 5/10/19.
// Copyright © 2019 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
class AboutViewController: NSViewController, NSTableViewDataSource, NSTableViewDelegate {
@IBOutlet weak var translatorsList: NSTableView!
private var languages = [
"Deutsch 🇩🇪",
"Ukrainian🇺🇦",
"Spanish 🇪🇸",
"Arabic 🇮🇶",
"Chinese 🇨🇳",
"Korean 🇰🇷",
"French 🇫🇷",
"Dutch 🇳🇱",
"Portuguese 🇵🇹",
"Italian 🇮🇹",
"Hebrew 🇮🇱",
"Chinese 🇨🇳",
"Portuguese 🇵🇹",
"Czech 🇨🇿",
"Hindi 🇮🇳",
"Turkish 🇹🇷",
"Chinese 🇹🇼🇭🇰🇲🇴"
]
private var authors = [
"Michael Barzmann",
"Olena Hlushchenko ♥️",
"aonez (aone@keka.io)",
"Ayad (@ayad0net)",
"Pertim (macwk.com@gmail.com)",
"Wonsup Yoon (pusnow@kaist.ac.kr)",
"Simon Jornet (github.com/jornetsimon)",
"Chris Hendriks (github.com/olikilo)",
"reddit.com/user/endallbeallknowitall",
"Leonardo Bartoletti - leodmc88@gmail.com",
"Will Pazner (github.com/pazner)",
"Holton Jiang (github.com/holton-jiang)",
"Vanessa C. (github.com/VChristinne)",
"Max Akrman (github.com/isametry)",
"Aagman (stscpns@gmail.com)",
"Bünyamin Erol (bunyaminerol.com.tr)",
"Wen Xiang (imwwx@icloud.com)"
]
override func viewDidLoad() {
if let dictionary = Bundle.main.infoDictionary,
let ver = dictionary["CFBundleShortVersionString"] as? String,
let build = dictionary["CFBundleVersion"] as? String {
versionLabel.stringValue = "Version \(ver) (\(build))"
versionLabel.isSelectable = true
}
translatorsList.delegate = self
translatorsList.dataSource = self
}
@IBOutlet weak var versionLabel: NSTextField!
@IBAction func openContributorsPage(_ sender: Any) {
let url = URL(string: "https://github.com/glushchenko/fsnotes/graphs/contributors")!
NSWorkspace.shared.open(url)
}
func numberOfRows(in tableView: NSTableView) -> Int {
return languages.count
}
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
let result = tableView.makeView(withIdentifier: (tableColumn?.identifier)!, owner: self) as! NSTableCellView
if tableColumn?.identifier.rawValue == "table.about.0" {
result.textField?.stringValue = languages[row]
} else {
result.textField?.stringValue = authors[row]
}
return result
}
}
================================================
FILE: FSNotes/AboutWindowController.swift
================================================
//
// AboutWindowController.swift
// FSNotes
//
// Created by Олександр Глущенко on 5/10/19.
// Copyright © 2019 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
class AboutWindowController: NSWindowController, NSWindowDelegate {
override func windowDidLoad() {
super.windowDidLoad()
self.window?.delegate = self
self.window?.title = "About"
}
}
================================================
FILE: FSNotes/AppDelegate+URLRoutes.swift
================================================
//
// AppDelegate+URLRoutes.swift
// FSNotes
//
// Created by Jeff Hanbury on 13/04/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import Foundation
import Cocoa
extension AppDelegate {
enum HandledSchemes: String {
case fsnotes = "fsnotes"
case nv = "nv"
case nvALT = "nvalt"
case file = "file"
}
enum FSNotesRoutes: String {
case find = "find"
case new = "new"
case open = "open"
}
enum NvALTRoutes: String {
case find = "find"
case blank = ""
case make = "make"
}
func application(_ application: NSApplication, open urls: [URL]) {
guard var url = urls.first,
let scheme = url.scheme
else { return }
let path = url.absoluteString.escapePlus()
if let escaped = URL(string: path) {
url = escaped
}
switch scheme {
case HandledSchemes.file.rawValue:
if nil != ViewController.shared() {
self.importNotes(urls: urls)
} else {
self.urls = urls
}
case HandledSchemes.fsnotes.rawValue:
FSNotesRouter(url)
case HandledSchemes.nv.rawValue,
HandledSchemes.nvALT.rawValue:
NvALTRouter(url)
default:
break
}
}
func importNotes(urls: [URL]) {
guard let vc = ViewController.shared() else { return }
var importedNote: Note? = nil
var sidebarIndex: Int? = nil
for url in urls {
if let items = vc.sidebarOutlineView.sidebarItems, let note = Storage.shared().getBy(url: url) {
if let sidebarItem = items.first(where: { ($0 as? SidebarItem)?.project == note.project || $0 as? Project == note.project }) {
sidebarIndex = vc.sidebarOutlineView.row(forItem: sidebarItem)
importedNote = note
}
} else if let project = Storage.shared().getDefault() {
let newUrl = vc.copy(project: project, url: url)
UserDataService.instance.focusOnImport = newUrl
UserDataService.instance.skipSidebarSelection = true
}
}
if let note = importedNote, let si = sidebarIndex {
vc.sidebarOutlineView.selectRowIndexes([si], byExtendingSelection: false)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.35, execute: {
vc.notesTableView.setSelected(note: note)
})
}
}
// MARK: - FSNotes routes
func FSNotesRouter(_ url: URL) {
guard let directive = url.host else { return }
switch directive {
case FSNotesRoutes.find.rawValue:
RouteFSNotesFind(url)
case FSNotesRoutes.new.rawValue:
RouteFSNotesNew(url)
case FSNotesRoutes.open.rawValue:
RouteFSNotesOpen(url)
default:
break
}
}
/// Handles URLs with the tag fsnotes://open/?tag=test
/// Handles URLs with the tag fsnotes://open/?title=Open+Or+Create+If+Not+Exist
///
func RouteFSNotesOpen(_ url: URL) {
guard let vc = ViewController.shared() else { return }
if let tag = url["tag"]?.removingPercentEncoding {
vc.sidebarOutlineView.select(tag: tag)
return
}
if let title = url["title"]?.removingPercentEncoding {
if let note = Storage.shared().getBy(titleOrName: title) {
if let txt = url["txt"] {
// Append txt
note.append(string: NSMutableAttributedString(string: txt + "\n\n"))
_ = note.save()
// Set last range
note.setSelectedRange(range: NSRange(location: note.content.length, length: 0))
}
// Reset UI and focus
vc.cleanSearchAndEditArea(shouldBecomeFirstResponder: false, completion: { () -> Void in
vc.notesTableView.selectRowAndSidebarItem(note: note)
NSApp.mainWindow?.makeFirstResponder(vc.editor)
vc.notesTableView.saveNavigationHistory(note: note)
})
// Create NEW
} else {
RouteFSNotesNew(url)
}
}
}
/// Handles URLs with the path /find/searchstring1%20searchstring2
func RouteFSNotesFind(_ url: URL) {
guard ViewController.shared() != nil else {
self.url = url
return
}
search(url: url)
}
public func search(url: URL) {
guard let vc = ViewController.shared() else { return }
var lastPath = url.lastPathComponent
if let wikiURL = url["id"] {
if let note = Storage.shared().getBy(titleOrName: wikiURL) {
vc.cleanSearchAndEditArea(shouldBecomeFirstResponder: false, completion: { () -> Void in
vc.notesTableView.selectRowAndSidebarItem(note: note)
NSApp.mainWindow?.makeFirstResponder(vc.editor)
vc.notesTableView.saveNavigationHistory(note: note)
})
return
} else {
lastPath = wikiURL
vc.search.window?.makeFirstResponder(vc.search)
}
}
search(query: lastPath)
}
func search(query: String) {
guard let controller = ViewController.shared() else { return }
let searchQuery = SearchQuery()
searchQuery.type = .All
searchQuery.setFilter(query)
controller.storage.setSearchQuery(value: searchQuery)
controller.updateTable() {
DispatchQueue.main.async {
controller.search.stringValue = query
if let note = controller.notesTableView.getNoteList().first {
if note.title.lowercased() == query.lowercased() {
controller.notesTableView.saveNavigationHistory(note: note)
controller.notesTableView.setSelected(note: note)
controller.view.window?.makeFirstResponder(controller.editor)
} else {
controller.search.suggestAutocomplete(note, filter: query)
}
}
}
}
}
/// Handles URLs with the following paths:
/// - fsnotes://make/?title=URI-escaped-title&html=URI-escaped-HTML-data
/// - fsnotes://make/?title=URI-escaped-title&txt=URI-escaped-plain-text
/// - fsnotes://make/?txt=URI-escaped-plain-text
///
/// The three possible parameters (title, txt, html) are all optional.
///
func RouteFSNotesNew(_ url: URL) {
let newWindow = url["open"] != nil
let folderName = url["folder"]
var title = ""
var body = ""
if let titleParam = url["title"] {
title = titleParam
}
if let txtParam = url["txt"] {
body = txtParam
} else if let htmlParam = url["html"] {
body = htmlParam
}
guard let vc = ViewController.shared() else {
self.newName = title
self.newContent = body
self.newWindow = newWindow
self.folderName = folderName
return
}
guard let note = vc.createNote(name: title, content: body, folderName: folderName, openInNewWindow: newWindow),
newWindow else { return }
vc.openInNewWindow(note: note)
}
// MARK: - nvALT routes, for compatibility
func NvALTRouter(_ url: URL) {
guard let directive = url.host else { return }
switch directive {
case NvALTRoutes.find.rawValue:
RouteNvAltFind(url)
case NvALTRoutes.make.rawValue:
RouteNvAltMake(url)
default:
RouteNvAltBlank(url)
break
}
}
/// Handle URLs in the format nv://find/searchstring1%20searchstring2
///
/// Note: this route is identical to the corresponding FSNotes route.
///
func RouteNvAltFind(_ url: URL) {
RouteFSNotesFind(url)
}
/// Handle URLs in the format nv://note%20title
///
/// Note: this route is an alias to the /find route above.
///
func RouteNvAltBlank(_ url: URL) {
let pathWithFind = url.absoluteString.replacingOccurrences(of: "://", with: "://find/")
guard let newURL = URL(string: pathWithFind) else { return }
RouteFSNotesFind(newURL)
}
/// Handle URLs in the format:
///
/// - nv://make/?title=URI-escaped-title&html=URI-escaped-HTML-data&tags=URI-escaped-tag-string
/// - nv://make/?title=URI-escaped-title&txt=URI-escaped-plain-text
/// - nv://make/?txt=URI-escaped-plain-text
///
/// The four possible parameters (title, txt, html and tags) are all optional.
///
func RouteNvAltMake(_ url: URL) {
let newWindow = url["open"] != nil
var title = ""
var body = ""
if let titleParam = url["title"] {
title = titleParam
}
if let txtParam = url["txt"] {
body = txtParam
}
else if let htmlParam = url["html"] {
body = htmlParam
}
if let tagsParam = url["tags"] {
body = body.appending("\n\nnvALT tags: \(tagsParam)")
}
guard let vc = ViewController.shared() else {
self.newName = title
self.newContent = body
self.newWindow = newWindow
return
}
guard let note = vc.createNote(name: title, content: body, openInNewWindow: newWindow),
newWindow else { return }
vc.openInNewWindow(note: note)
}
}
================================================
FILE: FSNotes/AppDelegate.swift
================================================
//
// AppDelegate.swift
// FSNotes
//
// Created by Oleksandr Glushchenko on 7/20/17.
// Copyright © 2017 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
import UserNotifications
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate {
var prefsWindowController: PrefsWindowController?
var aboutWindowController: AboutWindowController?
var statusItem: NSStatusItem?
public var urls: [URL]? = nil
public var url: URL? = nil
public var newName: String? = nil
public var newContent: String? = nil
public var folderName: String? = nil
public var newWindow: Bool = false
public static var mainWindowController: MainWindowController?
public static var noteWindows = [NSWindowController]()
public static var appTitle: String {
let name = Bundle.main.object(forInfoDictionaryKey: "CFBundleDisplayName") as? String
return name ?? Bundle.main.object(forInfoDictionaryKey: kCFBundleNameKey as String) as! String
}
public static var gitProgress: GitProgress?
func applicationWillFinishLaunching(_ notification: Notification) {
checkStorageChanges()
loadDockIcon()
if UserDefaultsManagement.showInMenuBar {
constructMenu()
}
if !UserDefaultsManagement.showDockIcon {
let transformState = ProcessApplicationTransformState(kProcessTransformToUIElementApplication)
var psn = ProcessSerialNumber(highLongOfPSN: 0, lowLongOfPSN: UInt32(kCurrentProcess))
TransformProcessType(&psn, transformState)
NSApp.setActivationPolicy(.accessory)
}
}
func applicationDidFinishLaunching(_ aNotification: Notification) {
// Ensure the font panel is closed when the app starts, in case it was
// left open when the app quit.
NSFontManager.shared.fontPanel(false)?.orderOut(self)
applyAppearance()
#if CLOUD_RELATED_BLOCK
if let iCloudDocumentsURL = FileManager.default.url(forUbiquityContainerIdentifier: nil)?.appendingPathComponent("Documents").standardized {
if (!FileManager.default.fileExists(atPath: iCloudDocumentsURL.path, isDirectory: nil)) {
do {
try FileManager.default.createDirectory(at: iCloudDocumentsURL, withIntermediateDirectories: true, attributes: nil)
} catch {
print("Home directory creation: \(error)")
}
}
}
#endif
if UserDefaultsManagement.storagePath == nil {
self.requestStorageDirectory()
return
}
let storyboard = NSStoryboard(name: "Main", bundle: nil)
guard let mainWC = storyboard.instantiateController(withIdentifier: "MainWindowController") as? MainWindowController else {
fatalError("Error getting main window controller")
}
AppDelegate.mainWindowController = mainWC
mainWC.window?.makeKeyAndOrderFront(nil)
}
func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool {
if (!flag) {
AppDelegate.mainWindowController?.makeNew()
}
return true
}
func applicationWillTerminate(_ notification: Notification) {
UserDefaultsManagement.crashedLastTime = false
AppDelegate.saveWindowsState()
Storage.shared().saveUploadPaths()
let webkitPreview = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("wkPreview")
try? FileManager.default.removeItem(at: webkitPreview)
let printDir = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("Print")
try? FileManager.default.removeItem(at: printDir)
let encryption = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("Encryption")
try? FileManager.default.removeItem(at: encryption)
var temporary = URL(fileURLWithPath: NSTemporaryDirectory())
temporary.appendPathComponent("ThumbnailsBig")
try? FileManager.default.removeItem(at: temporary)
let storyboard = NSStoryboard(name: "Main", bundle: nil)
guard let mainWC = storyboard.instantiateController(withIdentifier: "MainWindowController") as? MainWindowController else {
return
}
if let x = mainWC.window?.frame.origin.x, let y = mainWC.window?.frame.origin.y {
UserDefaultsManagement.lastScreenX = Int(x)
UserDefaultsManagement.lastScreenY = Int(y)
}
Storage.shared().saveProjectsCache()
print("Termination end, crash status: \(UserDefaultsManagement.crashedLastTime)")
}
private static func saveWindowsState() {
var result = [[String: Any]]()
let noteWindows = self.noteWindows.sorted(by: { $0.window!.orderedIndex > $1.window!.orderedIndex })
for windowController in noteWindows {
if let frame = windowController.window?.frame,
let data = try? NSKeyedArchiver.archivedData(withRootObject: frame, requiringSecureCoding: true),
let controller = windowController.contentViewController as? NoteViewController,
let note = controller.editor.note {
let key = windowController.window?.isKeyWindow == true
result.append(["frame": data, "preview": controller.editor.isPreviewEnabled(), "url": note.url, "main": false, "key": key])
}
}
// Main frame
if let vc = ViewController.shared(), let note = vc.editor?.note, let mainFrame = vc.view.window?.frame,
let data = try? NSKeyedArchiver.archivedData(withRootObject: mainFrame, requiringSecureCoding: true) {
let key = vc.view.window?.isKeyWindow == true
result.append(["frame": data, "preview": vc.editor.isPreviewEnabled(), "url": note.url, "main": true, "key": key])
}
let projectsData = try? NSKeyedArchiver.archivedData(withRootObject: result, requiringSecureCoding: true)
if let documentDir = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first {
try? projectsData?.write(to: documentDir.appendingPathComponent("editors.settings"))
}
}
private func applyAppearance() {
if UserDefaultsManagement.appearanceType == .Dark {
NSApp.appearance = NSAppearance.init(named: NSAppearance.Name.darkAqua)
UserDataService.instance.isDark = true
}
if UserDefaultsManagement.appearanceType == .Light {
NSApp.appearance = NSAppearance.init(named: NSAppearance.Name.aqua)
UserDataService.instance.isDark = false
}
if UserDefaultsManagement.appearanceType == .System, NSAppearance.current.isDark {
UserDataService.instance.isDark = true
}
}
private func restartApp() {
guard let resourcePath = Bundle.main.resourcePath else { return }
let url = URL(fileURLWithPath: resourcePath)
let path = url.deletingLastPathComponent().deletingLastPathComponent().absoluteString
let task = Process()
task.launchPath = "/usr/bin/open"
task.arguments = [path]
task.launch()
exit(0)
}
private func requestStorageDirectory() {
var directoryURL: URL? = nil
if let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first {
directoryURL = URL(fileURLWithPath: path)
}
let panel = NSOpenPanel()
panel.directoryURL = directoryURL
panel.allowsMultipleSelection = false
panel.canChooseDirectories = true
panel.canChooseFiles = false
panel.canCreateDirectories = true
panel.message = "Please select default storage directory"
panel.begin { (result) -> Void in
if result == .OK {
guard let url = panel.url else {
return
}
let bookmarks = SandboxBookmark.sharedInstance()
bookmarks.save(url: url)
UserDefaultsManagement.storageType = .custom
UserDefaultsManagement.customStoragePath = url.path
self.restartApp()
} else {
exit(EXIT_SUCCESS)
}
}
}
func constructMenu() {
statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.squareLength)
if let button = statusItem?.button, let image = NSImage(named: "menuBar") {
image.size.width = 20
image.size.height = 20
button.image = image
}
statusItem?.button?.action = #selector(AppDelegate.clickStatusBarItem(sender:))
statusItem?.button?.sendAction(on: [.leftMouseUp, .rightMouseUp])
}
public func attachMenu() {
let menu = NSMenu()
menu.addItem(NSMenuItem(title: NSLocalizedString("New Note", comment: ""), action: #selector(AppDelegate.new(_:)), keyEquivalent: "n"))
let newWindow = NSMenuItem(title: NSLocalizedString("New Note in New Window", comment: ""), action: #selector(AppDelegate.createInNewWindow(_:)), keyEquivalent: "n")
var modifier = NSEvent.modifierFlags
modifier.insert(.command)
modifier.insert(.shift)
newWindow.keyEquivalentModifierMask = modifier
menu.addItem(newWindow)
menu.addItem(NSMenuItem.separator())
menu.addItem(NSMenuItem(title: NSLocalizedString("Search and create", comment: ""), action: #selector(AppDelegate.searchAndCreate(_:)), keyEquivalent: "l"))
menu.addItem(NSMenuItem(title: NSLocalizedString("Settings", comment: ""), action: #selector(AppDelegate.openPreferences(_:)), keyEquivalent: ","))
let lock = NSMenuItem(title: NSLocalizedString("Lock All Encrypted", comment: ""), action: #selector(ViewController.shared()?.lockAll(_:)), keyEquivalent: "l")
lock.keyEquivalentModifierMask = [.command, .shift]
menu.addItem(lock)
menu.addItem(NSMenuItem.separator())
menu.addItem(NSMenuItem(title: NSLocalizedString("Quit FSNotes", comment: ""), action: #selector(NSApplication.terminate(_:)), keyEquivalent: "q"))
menu.delegate = self
statusItem?.menu = menu
}
@objc func clickStatusBarItem(sender: NSStatusItem) {
let event = NSApp.currentEvent!
if event.type == NSEvent.EventType.leftMouseUp {
// Hide active not hidden and not miniaturized
if !NSApp.isHidden && NSApp.isActive {
if let mainWindow = AppDelegate.mainWindowController?.window, !mainWindow.isMiniaturized {
NSApp.hide(nil)
return
}
}
NSApp.unhide(nil)
NSApp.activate(ignoringOtherApps: true)
AppDelegate.mainWindowController?.window?.makeKeyAndOrderFront(nil)
ViewController.shared()?.search.becomeFirstResponder()
return
}
attachMenu()
DispatchQueue.main.async {
if let statusItem = self.statusItem, let button = statusItem.button {
statusItem.menu?.popUp(positioning: nil, at: NSPoint(x: button.frame.origin.x, y: button.frame.height + 10), in: button)
}
}
}
func menuDidClose(_ menu: NSMenu) {
statusItem?.menu = nil
}
// MARK: IBActions
@IBAction func openMainWindow(_ sender: Any) {
AppDelegate.mainWindowController?.makeNew()
}
@IBAction func openHelp(_ sender: Any) {
NSWorkspace.shared.open(URL(string: "https://github.com/glushchenko/fsnotes/wiki")!)
}
@IBAction func openReportsAndRequests(_ sender: Any) {
NSWorkspace.shared.open(URL(string: "https://github.com/glushchenko/fsnotes/issues/new/choose")!)
}
@IBAction func openSite(_ sender: Any) {
NSWorkspace.shared.open(URL(string: "https://fsnot.es")!)
}
@IBAction func openPreferences(_ sender: Any?) {
if prefsWindowController == nil {
let storyboard = NSStoryboard(name: "Main", bundle: nil)
prefsWindowController = storyboard.instantiateController(withIdentifier: "Preferences") as? PrefsWindowController
}
guard let prefsWindowController = prefsWindowController else { return }
prefsWindowController.showWindow(nil)
prefsWindowController.window?.makeKeyAndOrderFront(prefsWindowController)
NSApp.activate(ignoringOtherApps: true)
}
@IBAction func new(_ sender: Any?) {
AppDelegate.mainWindowController?.makeNew()
NSApp.activate(ignoringOtherApps: true)
ViewController.shared()?.fileMenuNewNote(self)
}
@IBAction func createInNewWindow(_ sender: Any?) {
AppDelegate.mainWindowController?.makeNew()
NSApp.activate(ignoringOtherApps: true)
ViewController.shared()?.createInNewWindow(self)
}
@IBAction func searchAndCreate(_ sender: Any?) {
AppDelegate.mainWindowController?.makeNew()
NSApp.activate(ignoringOtherApps: true)
guard let vc = ViewController.shared() else { return }
DispatchQueue.main.async {
vc.search.window?.makeFirstResponder(vc.search)
}
}
@IBAction func removeMenuBar(_ sender: Any?) {
guard let statusItem = statusItem else { return }
NSStatusBar.system.removeStatusItem(statusItem)
}
@IBAction func addMenuBar(_ sender: Any?) {
constructMenu()
}
@IBAction func showAboutWindow(_ sender: AnyObject) {
if aboutWindowController == nil {
let storyboard = NSStoryboard(name: "Main", bundle: nil)
aboutWindowController = storyboard.instantiateController(withIdentifier: "About") as? AboutWindowController
}
guard let aboutWindowController = aboutWindowController else { return }
aboutWindowController.showWindow(nil)
aboutWindowController.window?.makeKeyAndOrderFront(aboutWindowController)
NSApp.activate(ignoringOtherApps: true)
}
public func loadDockIcon() {
var image: Image?
switch UserDefaultsManagement.dockIcon {
case 0:
image = NSImage(named: "modern")
break
case 1:
image = NSImage(named: "AppIconClassic")
break
default:
break
}
guard let im = image else { return }
let appDockTile = NSApplication.shared.dockTile
if #available(OSX 10.12, *) {
appDockTile.contentView = NSImageView(image: im)
}
appDockTile.display()
}
private func checkStorageChanges() {
if Storage.shared().shouldMovePrompt,
let local = UserDefaultsManagement.localDocumentsContainer,
let iCloudDrive = UserDefaultsManagement.iCloudDocumentsContainer
{
let message = NSLocalizedString("We are detect that you are install FSNotes from Mac App Store with default storage in iCloud Drive, do you want to move old database in iCloud Drive?", comment: "")
promptToMoveDatabase(from: local, to: iCloudDrive, messageText: message)
}
}
public func promptToMoveDatabase(from currentURL: URL, to url : URL, messageText: String) {
let alert = NSAlert()
alert.messageText = messageText
alert.informativeText =
NSLocalizedString("Otherwise, the database of your notes will be available at: ", comment: "") + currentURL.path
alert.alertStyle = .warning
alert.addButton(withTitle: NSLocalizedString("No", comment: ""))
alert.addButton(withTitle: NSLocalizedString("Yes", comment: ""))
if alert.runModal() == .alertSecondButtonReturn {
move(from: currentURL, to: url)
let localTrash = currentURL.appendingPathComponent("Trash", isDirectory: true)
let cloudTrash = url.appendingPathComponent("Trash", isDirectory: true)
move(from: localTrash, to: cloudTrash)
}
}
private func move(from currentURL: URL, to url: URL) {
if let list = try? FileManager.default.contentsOfDirectory(at: currentURL, includingPropertiesForKeys: nil, options: .init()) {
if !FileManager.default.fileExists(atPath: currentURL.path) {
return
}
if !FileManager.default.fileExists(atPath: url.path) {
try? FileManager.default.createDirectory(at: url, withIntermediateDirectories: true, attributes: nil)
}
for item in list {
let fileName = item.lastPathComponent
do {
let dst = url.appendingPathComponent(fileName)
try FileManager.default.moveItem(at: item, to: dst)
} catch {
if ["Trash", "Welcome"].contains(fileName) {
continue
}
let exist = NSAlert()
var message = NSLocalizedString("We can not move \"{DST_PATH}\" because this item already exist in selected destination.", comment: "")
message = message.replacingOccurrences(of: "{DST_PATH}", with: item.path)
exist.messageText = message
exist.addButton(withTitle: NSLocalizedString("OK", comment: ""))
exist.runModal()
}
}
}
}
func application(_ application: NSApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([NSUserActivityRestoring]) -> Void) -> Bool {
ViewController.shared()?.restoreUserActivityState(userActivity)
return true
}
func application(_ application: NSApplication, willContinueUserActivityWithType userActivityType: String) -> Bool {
return true
}
func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool {
return true
}
public static func getEditTextViews() -> [EditTextView] {
var views = getOpenedEditTextViews()
if let controller = mainWindowController?.contentViewController as? ViewController {
views.append(controller.editor)
}
return views
}
public static func getOpenedEditTextViews() -> [EditTextView] {
var views = [EditTextView]()
for window in noteWindows {
if let controller = window.contentViewController as? NoteViewController {
views.append(controller.editor)
}
}
return views
}
}
================================================
FILE: FSNotes/Base.lproj/Main.storyboard
================================================
NSAllRomanInputSourcesLocaleIdentifier
NSAllRomanInputSourcesLocaleIdentifier
NSAllRomanInputSourcesLocaleIdentifier
Copyright © 2017-2024 Oleksandr Hlushchenko.
All rights reserved.
Dylan Seeger — https://www.lovably.com
Olena Hlushcneko
NSAllRomanInputSourcesLocaleIdentifier
NSAllRomanInputSourcesLocaleIdentifier
NSAllRomanInputSourcesLocaleIdentifier
NSAllRomanInputSourcesLocaleIdentifier
================================================
FILE: FSNotes/EditorViewController+ScrollPosition.swift
================================================
//
// EditorViewController+ScrollPosition.swift
// FSNotes
//
// Created by Oleksandr Hlushchenko on 22.12.2025.
// Copyright © 2025 Oleksandr Hlushchenko. All rights reserved.
//
import Foundation
import AppKit
extension EditorViewController {
func initScrollObserver() {
if let textView = vcEditor, let scrollView = textView.enclosingScrollView {
NotificationCenter.default.addObserver(
self,
selector: #selector(scrollViewDidScroll),
name: NSView.boundsDidChangeNotification,
object: scrollView.contentView
)
scrollView.contentView.postsBoundsChangedNotifications = true
}
}
func restoreScrollPosition() {
guard let textView = vcEditor,
let charIndex = textView.note?.scrollPosition,
let layoutManager = textView.layoutManager,
let textContainer = textView.textContainer
else {
vcEditor?.isScrollPositionSaverLocked = false
return
}
layoutManager.ensureLayout(for: textContainer)
let glyphIndex = layoutManager.glyphIndexForCharacter(at: charIndex)
let rect = layoutManager.boundingRect(forGlyphRange: NSRange(location: glyphIndex, length: 1),
in: textContainer)
textView.scroll(rect.origin)
textView.isScrollPositionSaverLocked = false
}
@objc func scrollViewDidScroll(_ notification: Notification) {
guard notification.object as? NSClipView != nil else { return }
if let textView = vcEditor, !textView.isPreviewEnabled(), !textView.isScrollPositionSaverLocked {
guard
let layoutManager = textView.layoutManager,
let textContainer = textView.textContainer
else { return }
let visibleRect = textView.enclosingScrollView!.contentView.bounds
let glyphRange = layoutManager.glyphRange(forBoundingRect: visibleRect,
in: textContainer)
textView.note?.scrollPosition = layoutManager.characterIndexForGlyph(at: glyphRange.location)
}
}
}
================================================
FILE: FSNotes/EditorViewController+Sharing.swift
================================================
//
// EditorViewController+Sharing.swift
// FSNotes
//
// Created by Oleksandr Hlushchenko on 03.07.2022.
// Copyright © 2022 Oleksandr Hlushchenko. All rights reserved.
//
import Cocoa
extension EditorViewController: NSSharingServicePickerDelegate {
func sharingServicePicker(_ sharingServicePicker: NSSharingServicePicker, sharingServicesForItems items: [Any], proposedSharingServices proposedServices: [NSSharingService]) -> [NSSharingService] {
var share = proposedServices
if #available(macOS 11.0, *) {
guard let image = NSImage(systemSymbolName: "document.on.document", accessibilityDescription: nil),
let webImage = NSImage(named: "web") else {
return proposedServices
}
let titleWeb = NSLocalizedString("Web", comment: "")
let web = NSSharingService(title: titleWeb, image: webImage, alternateImage: nil, handler: {
ViewController.shared()?.uploadWebNote(NSMenuItem())
})
share.insert(web, at: 0)
let titlePlain = NSLocalizedString("Copy Plain Text", comment: "")
let plainText = NSSharingService(title: titlePlain, image: image, alternateImage: image, handler: {
self.saveTextAtClipboard()
})
share.insert(plainText, at: 1)
let titleHTML = NSLocalizedString("Copy HTML", comment: "")
let html = NSSharingService(title: titleHTML, image: image, alternateImage: image, handler: {
self.saveHtmlAtClipboard()
})
share.insert(html, at: 2)
}
return share
}
//MARK: Share Service
public func saveTextAtClipboard() {
if let note = vcEditor?.note {
let unloadedText = note.content.unloadTasks()
let pasteboard = NSPasteboard.general
pasteboard.declareTypes([NSPasteboard.PasteboardType.string], owner: nil)
pasteboard.setString(unloadedText.string, forType: NSPasteboard.PasteboardType.string)
}
}
public func saveHtmlAtClipboard() {
if let note = vcEditor?.note {
let unloadedText = note.content.unloadTasks()
if let render = renderMarkdownHTML(markdown: unloadedText.string) {
let pasteboard = NSPasteboard.general
pasteboard.declareTypes([NSPasteboard.PasteboardType.string], owner: nil)
pasteboard.setString(render, forType: NSPasteboard.PasteboardType.string)
}
}
}
}
================================================
FILE: FSNotes/EditorViewController.swift
================================================
//
// EditorViewController.swift
// FSNotes
//
// Created by Oleksandr Hlushchenko on 26.06.2022.
// Copyright © 2022 Oleksandr Hlushchenko. All rights reserved.
//
import Foundation
import AppKit
import LocalAuthentication
import WebKit
import UserNotifications
class EditorViewController: NSViewController, NSTextViewDelegate, NSMenuItemValidation {
public var alert: NSAlert?
public var noteLoading: ProgressState = .none
public var vcEditor: EditTextView?
public var vcTitleLabel: TitleTextField?
public var vcNonSelectedLabel: NSTextField?
public var vcPreviewButton: NSButton?
public var vcShareButton: NSButton?
public var vcLockUnlockButton: NSButton?
public var vcEditorScrollView: EditorScrollView?
public var previewResizeTimer = Timer()
public var rowUpdaterTimer = Timer()
public var editorUndoManager = UndoManager()
public var breakUndoTimer = Timer()
// git
public var snapshotsTimer = Timer()
public var lastSnapshot: Int?
public var pullTimer = Timer()
public var encPassword: NSSecureTextField?
public var encVerifyPassword: NSSecureTextField?
public var encCompletionHandler: ((String) -> Void)?
public func initView() {
guard let editor = vcEditor else { return }
editor.delegate = self
initScrollObserver()
editor.isGrammarCheckingEnabled = UserDefaultsManagement.grammarChecking
editor.isContinuousSpellCheckingEnabled = UserDefaultsManagement.continuousSpellChecking
editor.smartInsertDeleteEnabled = UserDefaultsManagement.smartInsertDelete
editor.isAutomaticSpellingCorrectionEnabled = UserDefaultsManagement.automaticSpellingCorrection
editor.isAutomaticQuoteSubstitutionEnabled = UserDefaultsManagement.automaticQuoteSubstitution
editor.isAutomaticDataDetectionEnabled = UserDefaultsManagement.automaticDataDetection
editor.isAutomaticLinkDetectionEnabled = UserDefaultsManagement.automaticLinkDetection
editor.isAutomaticTextReplacementEnabled = UserDefaultsManagement.automaticTextReplacement
editor.isAutomaticDashSubstitutionEnabled = UserDefaultsManagement.automaticDashSubstitution
}
deinit {
NotificationCenter.default.removeObserver(self)
}
func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
guard let vc = ViewController.shared() else { return false}
// Current note
var note = vc.editor.note
if note == nil {
note = vc.getSelectedNotes()?.first
}
let ident = menuItem.identifier?.rawValue
if let title = menuItem.menu?.identifier?.rawValue {
switch title {
case "fsnotesMenu":
if menuItem.identifier?.rawValue == "fsnotes.emptyBin" {
menuItem.keyEquivalentModifierMask = UserDefaultsManagement.focusInEditorOnNoteSelect
? [.command, .option, .shift]
: [.command, .shift]
menuItem.title = NSLocalizedString("Empty Bin", comment: "")
return true
}
case "fileMenu":
return vc.processFileMenuItems(menuItem, menuId: title)
case "shareMenu":
return vc.processShareMenuItems(menuItem, menuId: title)
case "folderMenu":
return vc.processLibraryMenuItems(menuItem, menuId: title)
case "findMenu":
guard let evc = NSApplication.shared.keyWindow?.contentViewController as? EditorViewController,
evc.vcEditor?.note != nil else { return false }
if evc.vcEditor?.markdownView == nil {
if ["findMenu.find",
"findMenu.findAndReplace",
"findMenu.next",
"findMenu.prev",
"findMenu.selectionToFind"
].contains(menuItem.identifier?.rawValue) {
return true
}
} else {
if ["findMenu.find",
"findMenu.next",
"findMenu.prev",
"findMenu.selectionToFind"
].contains(menuItem.identifier?.rawValue) {
return true
}
}
return false
case "viewSortBy":
let iconName = UserDefaultsManagement.sortDirection ? "arrow.down" : "arrow.up"
switch menuItem.tag {
case 1:
if UserDefaultsManagement.sort == .modificationDate {
if #available(macOS 11.0, *) {
menuItem.image = NSImage.init(systemSymbolName: iconName, accessibilityDescription: nil)
menuItem.state = .off
} else {
menuItem.state = .on
menuItem.image = NSImage()
}
} else {
menuItem.state = .off
menuItem.image = NSImage()
}
case 2:
if UserDefaultsManagement.sort == .creationDate {
if #available(macOS 11.0, *) {
menuItem.image = NSImage.init(systemSymbolName: iconName, accessibilityDescription: nil)
menuItem.state = .off
} else {
menuItem.state = .on
menuItem.image = NSImage()
}
} else {
menuItem.state = .off
menuItem.image = NSImage()
}
case 3:
if UserDefaultsManagement.sort == .title {
if #available(macOS 11.0, *) {
menuItem.image = NSImage.init(systemSymbolName: iconName, accessibilityDescription: nil)
menuItem.state = .off
} else {
menuItem.state = .on
menuItem.image = NSImage()
}
} else {
menuItem.state = .off
menuItem.image = NSImage()
}
default:
break
}
case "showInSidebar":
switch menuItem.tag {
case 1:
menuItem.state = UserDefaultsManagement.sidebarVisibilityInbox ? .on : .off
case 2:
menuItem.state = UserDefaultsManagement.sidebarVisibilityNotes ? .on : .off
case 3:
menuItem.state = UserDefaultsManagement.sidebarVisibilityTodo ? .on : .off
case 5:
menuItem.state = UserDefaultsManagement.sidebarVisibilityTrash ? .on : .off
case 6:
menuItem.state = UserDefaultsManagement.sidebarVisibilityUntagged ? .on : .off
default:
break
}
case "viewMenu":
switch ident {
case "previewMathJax":
menuItem.state = UserDefaultsManagement.mathJaxPreview ? .on : .off
break
case "viewMenu.historyBack":
if vc.notesTableView.historyPosition == 0 {
return false
}
break
case "viewMenu.historyForward":
if vc.notesTableView.historyPosition == vc.notesTableView.history.count - 1 {
return false
}
break
case "view.toggleNoteList":
menuItem.title = vc.isVisibleNoteList()
? NSLocalizedString("Hide Note List", comment: "")
: NSLocalizedString("Show Note List", comment: "")
break
case "view.toggleSidebar":
menuItem.title = vc.isVisibleSidebar()
? NSLocalizedString("Hide Sidebar", comment: "")
: NSLocalizedString("Show Sidebar", comment: "")
break
case "viewMenu.actualSize":
return UserDefaultsManagement.fontSize != UserDefaultsManagement.DefaultFontSize
default:
break
}
default:
break
}
}
return true
}
public func getSelectedNotes() -> [Note]? {
// Opened window
if NSApplication.shared.keyWindow?.contentViewController?.isKind(of: NoteViewController.self) == true,
let evc = NSApplication.shared.keyWindow?.contentViewController as? EditorViewController,
let note = evc.vcEditor?.note {
return [note]
}
// Active main window
if let cvc = NSApplication.shared.keyWindow?.contentViewController,
cvc.isKind(of: ViewController.self),
let vc = ViewController.shared(),
let selected = vc.notesTableView.getSelectedNotes() {
return selected
}
return nil
}
public func getSelectedNote() -> Note? {
// Opened window
if NSApplication.shared.keyWindow?.contentViewController?.isKind(of: NoteViewController.self) == true,
let evc = NSApplication.shared.keyWindow?.contentViewController as? EditorViewController,
let note = evc.vcEditor?.note {
return note
}
// Active main window
if let cvc = NSApplication.shared.keyWindow?.contentViewController,
cvc.isKind(of: ViewController.self),
let vc = ViewController.shared(),
let selected = vc.notesTableView.getSelectedNotes()?.first {
return selected
}
return nil
}
private func isFirstResponder(responder: AnyClass) -> Bool {
return view.window?.firstResponder?.isKind(of: responder) == true
}
private func isOpenedInNewWindow() -> Bool {
return NSApplication.shared.keyWindow?.contentViewController?.isKind(of: NoteViewController.self) == true
}
// MARK: Window bar actions
@IBAction func textFinder(_ sender: NSMenuItem) {
guard let evc = NSApplication.shared.keyWindow?.contentViewController as? EditorViewController,
evc.vcEditor?.note != nil
else { return }
if let mView = evc.vcEditor?.markdownView {
mView.performTextFinderAction(sender)
return
}
if let editView = evc.vcEditor {
editView.performFindPanelAction(sender)
}
}
@IBAction func fsToggleLockItem(_ sender: NSMenuItem) {
guard let vc = ViewController.shared() else { return }
if isFirstResponder(responder: SidebarOutlineView.self) {
vc.sidebarOutlineView.toggleFolderLock(sender)
return
}
if isFirstResponder(responder: NotesTableView.self) ||
isFirstResponder(responder: EditTextView.self) ||
isOpenedInNewWindow() {
vc.toggleNotesLock(sender)
return
}
}
@IBAction func fsDecryptItem(_ sender: NSMenuItem) {
guard let vc = ViewController.shared() else { return }
if isFirstResponder(responder: SidebarOutlineView.self) {
vc.sidebarOutlineView.removeFolderEncryption(sender)
return
}
if isFirstResponder(responder: NotesTableView.self) || isOpenedInNewWindow() {
vc.removeNoteEncryption(sender)
return
}
}
@IBAction func fsRevealItem(_ sender: NSMenuItem) {
guard let vc = ViewController.shared() else { return }
if isFirstResponder(responder: SidebarOutlineView.self) {
vc.sidebarOutlineView.revealInFinder(sender)
return
}
if isFirstResponder(responder: NotesTableView.self) ||
isFirstResponder(responder: EditTextView.self) ||
isOpenedInNewWindow() {
vc.finderMenu(sender)
return
}
}
@IBAction func fsRenameItem(_ sender: NSMenuItem) {
guard let vc = ViewController.shared() else { return }
if isFirstResponder(responder: SidebarOutlineView.self) || isOpenedInNewWindow() {
vc.sidebarOutlineView.renameFolderMenu(sender)
return
}
if isFirstResponder(responder: NotesTableView.self) ||
isFirstResponder(responder: EditTextView.self) {
vc.renameMenu(sender)
return
}
}
@IBAction func toggleNotesLock(_ sender: Any) {
guard let vc = ViewController.shared(),
let evc = NSApplication.shared.keyWindow?.contentViewController as? EditorViewController else { return }
let isOpenedWindow = NSApplication.shared.keyWindow?.contentViewController?.isKind(of: NoteViewController.self) == true
var notes = vc.getSelectedNotes()
if isOpenedWindow, let note = evc.vcEditor?.note {
notes = [note]
}
guard let first = notes?.first, let notes = notes else { return }
// Lock unlocked
if first.isUnlocked() {
_ = lockUnlocked(notes: notes)
return
}
// Unlock encrypted
if first.container == .encryptedTextPack {
getMasterPassword() { password in
guard password.count > 0 else { return }
for note in notes {
guard note.isEncryptedAndLocked(), note.unLock(password: password) else { continue }
let insertTags = note.scanContentTags().0
DispatchQueue.main.async {
self.reloadAllOpenedWindows(note: note)
ViewController.shared()?.sidebarOutlineView?.addTags(insertTags)
ViewController.shared()?.notesTableView.reloadRow(note: note)
}
}
}
return
}
// Encrypt plain
getMasterPassword(forEncrypt: true) { password in
for note in notes {
if !note.isEncrypted(), note.encrypt(password: password) {
note.password = nil
DispatchQueue.main.async {
self.reloadAllOpenedWindows(note: note)
ViewController.shared()?.focusTable()
ViewController.shared()?.notesTableView.reloadRow(note: note)
}
}
}
}
}
@IBAction func openProjectViewSettings(_ sender: NSMenuItem) {
guard let vc = ViewController.shared() else {
return
}
if let controller = vc.storyboard?.instantiateController(withIdentifier: "ProjectSettingsViewController")
as? ProjectSettingsViewController {
vc.projectSettingsViewController = controller
if let project = vc.sidebarOutlineView.getSelectedProject() {
vc.presentAsSheet(controller)
controller.load(project: project)
}
}
}
@IBAction func createFolder(_ sender: Any) {
guard let vc = ViewController.shared(),
let sidebarOutlineView = vc.sidebarOutlineView else { return }
// Call from menu bar
if let sender = sender as? NSMenuItem, sender.identifier?.rawValue == "fileMenu.attach" {
sidebarOutlineView.addRoot()
return
}
// Call from popup menu or menu bar
var project = sidebarOutlineView.getSelectedProject()
if project == nil || project?.isVirtual == true || !isFirstResponder(responder: SidebarOutlineView.self) {
project = Storage.shared().getDefault()
}
guard let project = project, let window = MainWindowController.shared() else { return }
let alert = NSAlert()
vc.alert = alert
let field = NSTextField(frame: NSRect(x: 0, y: 0, width: 290, height: 20))
alert.messageText = NSLocalizedString("New project", comment: "")
alert.informativeText = NSLocalizedString("Please enter project name:", comment: "")
alert.accessoryView = field
alert.alertStyle = .informational
alert.addButton(withTitle: NSLocalizedString("Add", comment: ""))
alert.addButton(withTitle: NSLocalizedString("Cancel", comment: ""))
alert.beginSheetModal(for: window) { (returnCode: NSApplication.ModalResponse) -> Void in
if returnCode == NSApplication.ModalResponse.alertFirstButtonReturn {
let name = field.stringValue
guard name.count > 0 else { return }
OperationQueue.main.addOperation {
vc.sidebarOutlineView.createProject(in: project, with: name)
}
}
NSApp.mainWindow?.makeFirstResponder(sidebarOutlineView)
vc.alert = nil
}
field.becomeFirstResponder()
}
@IBAction func togglePreview(_ sender: Any) {
guard let editor = vcEditor else { return }
let firstResp = view.window?.firstResponder
editor.togglePreviewState()
if (editor.isPreviewEnabled()) {
//Preview mode doesn't support text search
cancelTextSearch()
refillEditArea(force: true)
if let mdView = vcEditor?.editorViewController?.vcEditor?.markdownView {
view.window?.makeFirstResponder(mdView)
}
} else {
disablePreview()
}
if let responder = firstResp, (
ViewController.shared()?.search.currentEditor() == firstResp
|| responder.isKind(of: NotesTableView.self)
|| responder.isKind(of: SidebarOutlineView.self)
) {
view.window?.makeFirstResponder(firstResp)
} else {
var responder: NSResponder? = vcEditor
if vcEditor?.isPreviewEnabled() == true, let mView = vcEditor?.markdownView {
responder = mView
}
if let responder = responder {
view.window?.makeFirstResponder(responder)
}
}
vcEditor?.userActivity?.needsSave = true
editor.note?.project.saveNotesPreview()
}
@IBAction func toggleMathJax(_ sender: NSMenuItem) {
sender.state = sender.state == .on ? .off : .on
UserDefaultsManagement.mathJaxPreview = sender.state == .on
refillEditArea(force: true)
}
@IBAction func shareSheet(_ sender: NSButton) {
if let note = vcEditor?.note {
let sharingPicker = NSSharingServicePicker(items: [
note.content,
note.url
])
sharingPicker.delegate = self
sharingPicker.show(relativeTo: NSZeroRect, of: sender, preferredEdge: .minY)
}
}
// MARK: File menu
@IBAction func printNotes(_ sender: NSMenuItem) {
guard let notes = getSelectedNotes(), let note = notes.first else { return }
if note.isMarkdown() {
printMarkdownPreview()
return
}
let pv = NSTextView(frame: NSMakeRect(0, 0, 528, 688))
pv.textStorage?.append(note.content)
let printInfo = NSPrintInfo.shared
printInfo.isHorizontallyCentered = false
printInfo.isVerticallyCentered = false
printInfo.scalingFactor = 1
printInfo.topMargin = 40
printInfo.leftMargin = 40
printInfo.rightMargin = 40
printInfo.bottomMargin = 40
let operation: NSPrintOperation = NSPrintOperation(view: pv, printInfo: printInfo)
operation.printPanel.options.insert(NSPrintPanel.Options.showsPaperSize)
operation.printPanel.options.insert(NSPrintPanel.Options.showsOrientation)
operation.run()
}
@IBAction func finderMenu(_ sender: NSMenuItem) {
guard let notes = getSelectedNotes() else { return }
var urls = [URL]()
for note in notes {
urls.append(note.url)
}
NSWorkspace.shared.activateFileViewerSelecting(urls)
}
@IBAction func pinMenu(_ sender: Any) {
guard let notes = getSelectedNotes() else { return }
ViewController.shared()?.pin(selectedNotes: notes, toggle: true)
}
@IBAction func editorMenu(_ sender: Any) {
guard let notes = getSelectedNotes() else { return }
ViewController.shared()?.external(selectedNotes: notes)
}
@IBAction func copyURL(_ sender: Any) {
guard let note = getSelectedNotes()?.first else { return }
if let title = note.title.addingPercentEncoding(withAllowedCharacters: .alphanumerics) {
let name = "fsnotes://find?id=\(title)"
let pasteboard = NSPasteboard.general
pasteboard.declareTypes([NSPasteboard.PasteboardType.string], owner: nil)
pasteboard.setString(name, forType: NSPasteboard.PasteboardType.string)
UNUserNotificationCenter.current().getNotificationSettings { settings in
guard settings.authorizationStatus == .notDetermined else { return }
UNUserNotificationCenter.current().requestAuthorization(
options: [.alert, .sound]
) { _, _ in }
}
let content = UNMutableNotificationContent()
content.title = NSLocalizedString("URL has been copied to clipboard", comment: "")
content.body = name
content.sound = .default
UNUserNotificationCenter.current().add(
UNNotificationRequest(
identifier: UUID().uuidString,
content: content,
trigger: nil
))
}
}
@IBAction func copyTitle(_ sender: Any) {
guard let note = getSelectedNotes()?.first else { return }
let pasteboard = NSPasteboard.general
pasteboard.declareTypes([NSPasteboard.PasteboardType.string], owner: nil)
pasteboard.setString(note.title, forType: NSPasteboard.PasteboardType.string)
}
@IBAction func removeNoteEncryption(_ sender: Any) {
guard var notes = getSelectedNotes(),
let vc = ViewController.shared() else { return }
notes = decryptUnlocked(notes: notes)
guard notes.count > 0 else { return }
getMasterPassword() { password in
for note in notes {
if note.container == .encryptedTextPack {
let success = note.unEncrypt(password: password)
if success && notes.count == 0x01 {
note.password = nil
DispatchQueue.main.async {
self.reloadAllOpenedWindows(note: note)
}
}
}
vc.notesTableView.reloadRow(note: note)
}
}
}
@IBAction func changeCreationDate(_ sender: Any) {
guard let notes = getSelectedNotes() else { return }
guard let note = notes.first else { return }
guard let creationDate = note.getFileCreationDate() else { return }
guard let window = view.window else { return }
alert = NSAlert()
let field = NSTextField(frame: NSRect(x: 0, y: 0, width: 290, height: 20))
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let date = formatter.string(from: creationDate)
field.stringValue = date
field.placeholderString = "2020-08-28 21:59:07"
alert?.messageText = NSLocalizedString("Change Creation Date", comment: "Menu") + ":"
alert?.accessoryView = field
alert?.alertStyle = .informational
alert?.addButton(withTitle: "OK")
alert?.beginSheetModal(for: window) { (returnCode: NSApplication.ModalResponse) -> Void in
if returnCode == NSApplication.ModalResponse.alertFirstButtonReturn {
for note in notes {
if note.setCreationDate(string: field.stringValue) {
ViewController.shared()?.notesTableView.reloadRow(note: note)
}
}
}
self.alert = nil
}
field.becomeFirstResponder()
}
@IBAction func createInNewWindow(_ sender: Any) {
var content = String()
if let inlineTags = ViewController.shared()?.sidebarOutlineView.getSelectedInlineTags() {
content = inlineTags
}
if let note = createNote(content: content, openInNewWindow: true) {
openInNewWindow(note: note)
}
}
@IBAction func quickNote(_ sender: Any) {
if let note = createNote(content: "", openInNewWindow: true) {
NSApp.activate(ignoringOtherApps: true)
if !NSApp.isActive {
AppDelegate.mainWindowController?.window?.miniaturize(self)
}
openInNewWindow(note: note)
}
}
@IBAction func historyMenu(_ sender: Any) {
guard let cvc = NSApplication.shared.keyWindow?.contentViewController,
let vc = ViewController.shared(),
let note = getSelectedNotes()?.first else { return }
let moveMenu = NSMenu()
moveMenu.identifier = NSUserInterfaceItemIdentifier("fileMenu.history")
let commits = note.getCommits()
// Port
if commits.count == 0 {
return
}
for commit in commits {
let menuItem = NSMenuItem()
menuItem.title = commit.getDate()
menuItem.representedObject = commit
menuItem.action = #selector(vc.checkoutRevision(_:))
moveMenu.addItem(menuItem)
}
let general = moveMenu.item(at: 0)
// Main window
if cvc.isKind(of: ViewController.self),
vc.notesTableView.selectedRow >= 0 {
let view = vc.notesTableView.rect(ofRow: vc.notesTableView.selectedRow)
let x = vc.splitView.subviews[0].frame.width + 5
moveMenu.popUp(positioning: general, at: NSPoint(x: x, y: view.origin.y + 8), in: vc.notesTableView)
return
}
// Opened in new window
if cvc.isKind(of: NoteViewController.self) {
moveMenu.popUp(positioning: general, at: NSPoint(x: view.frame.width + 10, y: view.frame.height - 5), in: view)
}
}
@IBAction func duplicate(_ sender: Any) {
guard let notes = getSelectedNotes() else { return }
for note in notes {
let src = note.url
let dst = NameHelper.generateCopy(file: note.url)
if note.isTextBundle() || note.isEncrypted() {
try? FileManager.default.copyItem(at: src, to: dst)
continue
}
let name = dst.deletingPathExtension().lastPathComponent
let noteDupe = Note(name: name, project: note.project, type: note.type, cont: note.container)
noteDupe.content = NSMutableAttributedString(string: note.content.string)
// Clone images
if note.type == .Markdown && note.container == .none {
let images = note.content.getImagesAndFiles()
for image in images {
noteDupe.move(from: image.url, imagePath: image.path, to: note.project, copy: true)
}
}
if noteDupe.save() {
Storage.shared().add(noteDupe)
}
ViewController.shared()?.notesTableView.insertRows(notes: [noteDupe])
}
}
@IBAction func importNote(_ sender: NSMenuItem) {
guard let vc = ViewController.shared() else { return }
let panel = NSOpenPanel()
panel.allowsMultipleSelection = true
panel.canChooseDirectories = false
panel.canChooseFiles = true
panel.canCreateDirectories = false
panel.begin { (result) -> Void in
if result == NSApplication.ModalResponse.OK {
let urls = panel.urls
if let project = vc.sidebarOutlineView.getSelectedProject() ?? Storage.shared().getDefault() {
for url in urls {
_ = vc.copy(project: project, url: url)
}
}
}
}
}
@objc func moveNote(_ sender: NSMenuItem) {
let project = sender.representedObject as! Project
guard let notes = getSelectedNotes() else { return }
ViewController.shared()?.moveReq(notes: notes, project: project) { success in
guard success else { return }
if let cvc = NSApplication.shared.keyWindow?.contentViewController,
cvc.isKind(of: NoteViewController.self) {
self.updateTitle(note: notes.first!)
}
}
}
@IBAction func toggleContainer(_ sender: NSMenuItem) {
guard let notes = getSelectedNotes() else { return }
var newContainer: NoteContainer = .textBundleV2
if notes.first?.container == .textBundle || notes.first?.container == .textBundleV2 {
newContainer = .none
}
for note in notes {
if note.container == .encryptedTextPack {
continue
}
note.convertContainer(to: newContainer)
}
}
@IBAction func openWindow(_ sender: Any) {
guard let currentNote = ViewController.shared()?.notesTableView.getSelectedNote() else { return }
openInNewWindow(note: currentNote)
}
@IBAction func moveMenu(_ sender: Any) {
guard let vc = ViewController.shared() else { return }
// Move menu right from notes table view
if let cvc = NSApplication.shared.keyWindow?.contentViewController, cvc.isKind(of: ViewController.self) {
if vc.notesTableView.selectedRow >= 0 {
vc.loadMoveMenu()
let moveTitle = NSLocalizedString("Move", comment: "Menu")
let moveMenu = vc.noteMenu.item(withTitle: moveTitle)
let view = vc.notesTableView.rect(ofRow: vc.notesTableView.selectedRow)
let x = vc.splitView.subviews[0].frame.width + 5
let general = moveMenu?.submenu?.item(at: 0)
moveMenu?.submenu?.popUp(positioning: general, at: NSPoint(x: x, y: view.origin.y + 8), in: vc.notesTableView)
}
return
// Move menu right from window
} else {
vc.loadMoveMenu()
let moveTitle = NSLocalizedString("Move", comment: "Menu")
let moveMenu = vc.noteMenu.item(withTitle: moveTitle)
let general = moveMenu?.submenu?.item(at: 0)
moveMenu?.submenu?.popUp(positioning: general, at: NSPoint(x: view.frame.width + 10, y: view.frame.height - 5), in: view)
}
}
public func removeNotes(notes: [Note], forceRemove: Bool = false, rows: IndexSet? = nil) {
guard let vc = ViewController.shared() else { return }
let si = vc.getSidebarItem()
if si?.isTrash() == true || forceRemove {
vc.removeForever()
// Call from window, close it!
if let cvc = NSApplication.shared.keyWindow?.contentViewController,
cvc.isKind(of: NoteViewController.self) {
DispatchQueue.main.async {
self.view.window?.close()
}
}
return
}
let currentNote = vc.editor.note
let shouldClearEditor = currentNote != nil && notes.contains(where: { $0 === currentNote })
UserDataService.instance.searchTrigger = true
vc.notesTableView.removeRows(notes: notes)
// Delete tags
for note in notes {
let tags = note.tags
note.tags.removeAll()
vc.sidebarOutlineView.removeTags(tags)
}
vc.storage.removeNotes(notes: notes) { urlMapping in
if let md = AppDelegate.mainWindowController {
let undoManager = md.notesListUndoManager
if let ntv = vc.notesTableView {
// Register undo (restore)
undoManager.registerUndo(withTarget: ntv, selector: #selector(ntv.unDelete), object: urlMapping)
undoManager.setActionName(NSLocalizedString("Delete", comment: ""))
}
if let rows = rows, let minRow = rows.min(), minRow > -1 {
let qty = vc.notesTableView.countNotes()
if qty > minRow {
vc.notesTableView.selectRow(minRow)
} else {
vc.notesTableView.selectRow(qty - 1)
}
}
UserDataService.instance.searchTrigger = false
}
if shouldClearEditor {
vc.editor.clear()
}
}
// Call from window, close it!
if let cvc = NSApplication.shared.keyWindow?.contentViewController,
cvc.isKind(of: NoteViewController.self) {
DispatchQueue.main.async {
self.view.window?.close()
}
return
}
// If is main window – focus to notes list
if let cvc = NSApplication.shared.keyWindow?.contentViewController,
cvc.isKind(of: ViewController.self) {
NSApp.mainWindow?.makeFirstResponder(vc.notesTableView)
}
}
@IBAction func actualSize(_ sender: Any) {
UserDefaultsManagement.codeFont = NSFont(descriptor: UserDefaultsManagement.codeFont.fontDescriptor, size: CGFloat(UserDefaultsManagement.DefaultFontSize))!
UserDefaultsManagement.noteFont = NSFont(descriptor: UserDefaultsManagement.noteFont.fontDescriptor, size: CGFloat(UserDefaultsManagement.DefaultFontSize))!
ViewController.shared()?.reloadFonts()
}
@IBAction func zoomIn(_ sender: Any) {
UserDefaultsManagement.codeFont = NSFont(descriptor: UserDefaultsManagement.codeFont.fontDescriptor, size: UserDefaultsManagement.codeFont.pointSize + 1)!
UserDefaultsManagement.noteFont = NSFont(descriptor: UserDefaultsManagement.noteFont.fontDescriptor, size: UserDefaultsManagement.noteFont.pointSize + 1)!
ViewController.shared()?.reloadFonts()
}
@IBAction func zoomOut(_ sender: Any) {
UserDefaultsManagement.codeFont = NSFont(descriptor: UserDefaultsManagement.codeFont.fontDescriptor, size: UserDefaultsManagement.codeFont.pointSize - 1)!
UserDefaultsManagement.noteFont = NSFont(descriptor: UserDefaultsManagement.noteFont.fontDescriptor, size: UserDefaultsManagement.noteFont.pointSize - 1)!
ViewController.shared()?.reloadFonts()
}
@IBAction func showBackLinks(_ sender: NSMenuItem) {
if let appDelegate = NSApplication.shared.delegate as? AppDelegate,
let cvc = NSApplication.shared.keyWindow?.contentViewController as? EditorViewController,
let note = cvc.vcEditor?.note {
ViewController.shared()?.editor.clear()
appDelegate.search(query: "[[" + note.title + "]]")
}
}
// MARK: Dep methods
public func openInNewWindow(note: Note, frame: NSRect? = nil, preview: Bool = false) {
guard let windowController = NSStoryboard(name: "Main", bundle: nil)
.instantiateController(withIdentifier: "noteWindowController") as? NSWindowController else { return }
windowController.showWindow(nil)
windowController.window?.makeKeyAndOrderFront(windowController)
let viewController = windowController.contentViewController as! NoteViewController
viewController.initWindow()
viewController.editor.changePreviewState(preview)
viewController.editor.fill(note: note)
if note.isEncryptedAndLocked() {
viewController.lockUnlockButton.image = NSImage(named: NSImage.lockLockedTemplateName)
viewController.toggleNotesLock(self)
} else {
viewController.lockUnlockButton.image = NSImage(named: NSImage.lockUnlockedTemplateName)
}
AppDelegate.noteWindows.insert(windowController, at: 0)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
if let frame = frame {
windowController.window?.setFrame(frame, display: true)
}
viewController.view.window?.makeFirstResponder(viewController.editor)
}
}
func cancelTextSearch() {
let menu = NSMenuItem(title: "", action: nil, keyEquivalent: "")
menu.tag = NSTextFinder.Action.hideFindInterface.rawValue
vcEditor?.performTextFinderAction(menu)
}
func disablePreview() {
guard let textView = self.vcEditor else { return }
textView.disablePreviewEditorAndNote()
textView.markdownView?.getScrollPosition { point in
self.vcEditor?.note?.contentOffsetWeb = point
}
textView.markdownView?.removeFromSuperview()
textView.markdownView = nil
textView.subviews.removeAll(where: { $0.isKind(of: MPreviewView.self) })
refillEditArea()
}
public func viewDidResize() {
guard vcEditor?.isPreviewEnabled() == true else { return }
if noteLoading != .incomplete {
previewResizeTimer.invalidate()
previewResizeTimer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(reloadPreview), userInfo: nil, repeats: false)
}
}
@objc private func reloadPreview() {
DispatchQueue.main.async {
MPreviewView.template = nil
self.refillEditArea(force: true)
}
}
public func updateTitle(note: Note) {
guard let vcTitleLabel = vcTitleLabel else { return }
var titleString = note.getFileName()
if titleString.isValidUUID {
titleString = String()
}
if titleString.count > 0 {
vcTitleLabel.stringValue = note.project.getNestedLabel() + " › " + titleString
} else {
vcTitleLabel.stringValue = note.project.getNestedLabel()
}
vcTitleLabel.currentEditor()?.selectedRange = NSRange(location: 0, length: 0)
view.window?.title = vcTitleLabel.stringValue
}
func refillEditArea(force: Bool = false) {
noteLoading = .incomplete
vcPreviewButton?.state = vcEditor?.isPreviewEnabled() == true ? .on : .off
if let note = vcEditor?.note {
vcEditor?.fill(note: note, force: force)
}
noteLoading = .done
}
public func unLock(notes: [Note]) {
getMasterPassword() { password in
guard password.count > 0 else { return }
var i = 0
for note in notes {
let success = note.unLock(password: password)
if success {
let insertTags = note.scanContentTags().0
DispatchQueue.main.async {
ViewController.shared()?.sidebarOutlineView?.addTags(insertTags)
ViewController.shared()?.notesTableView.reloadRow(note: note)
}
if i == 0 {
note.password = password
DispatchQueue.main.async {
self.reloadAllOpenedWindows(note: note)
}
}
}
i = i + 1
}
}
}
public func reloadAllOpenedWindows(note: Note) {
let editors = AppDelegate.getEditTextViews()
for editor in editors {
if editor.note == note {
editor.editorViewController?.refillEditArea(force: true)
let lockIcon = note.isEncryptedAndLocked()
? NSImage.lockLockedTemplateName
: NSImage.lockUnlockedTemplateName
let lockImage = NSImage(named: lockIcon)
if let noteVC = editor.editorViewController as? NoteViewController {
noteVC.lockUnlockButton.image = lockImage
}
if let mainVC = editor.editorViewController as? ViewController {
mainVC.lockUnlock.image = lockImage
}
editor.window?.makeFirstResponder(editor)
}
}
}
public func closeAllOpenedWindows(where note: Note) {
for editor in AppDelegate.getOpenedEditTextViews() {
if editor.note == note {
editor.window?.close()
}
}
}
public func getMasterPassword(forEncrypt: Bool = false, completion: @escaping (String) -> ()) {
if #available(OSX 10.12.2, *), UserDefaultsManagement.allowTouchID {
let context = LAContext()
context.localizedFallbackTitle = NSLocalizedString("Enter Master Password", comment: "")
var passwordExist = false
do {
let item = KeychainPasswordItem(service: KeychainConfiguration.serviceName, account: "Master Password")
let password = try item.readPassword()
passwordExist = password.count > 0
} catch {/*_*/}
guard passwordExist && context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil) else {
masterPasswordPrompt(validation: forEncrypt, completion: completion)
return
}
context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: "To access secure data") { (success, evaluateError) in
// Skip if cancelled
if let error = evaluateError as NSError? {
if error.code == LAError.userCancel.rawValue || error.code == LAError.appCancel.rawValue {
return
}
}
// Press enter password or failed TouchID
if !success {
self.masterPasswordPrompt(validation: forEncrypt, completion: completion)
return
}
do {
let item = KeychainPasswordItem(service: KeychainConfiguration.serviceName, account: "Master Password")
let password = try item.readPassword()
completion(password)
return
} catch {
print("Keychain error: \(error.localizedDescription)")
}
// No password in keychain
self.masterPasswordPrompt(validation: forEncrypt, completion: completion)
}
} else {
// Bio is not available or disabled
masterPasswordPrompt(validation: forEncrypt, completion: completion)
}
}
@IBAction func onOkClick(_ sender: Any?) {
guard
let passwordField = encPassword,
let verifyPasswordField = encVerifyPassword,
let window = self.view.window
else { return }
if passwordField.stringValue.count == 0 {
let alert = NSAlert()
alert.alertStyle = .critical
alert.informativeText = NSLocalizedString("Please try again", comment: "")
alert.messageText = NSLocalizedString("Empty password", comment: "")
alert.beginSheetModal(for: window) { (returnCode: NSApplication.ModalResponse) -> Void in }
return
}
if passwordField.stringValue != verifyPasswordField.stringValue {
let alert = NSAlert()
alert.alertStyle = .critical
alert.informativeText = NSLocalizedString("Please try again", comment: "")
alert.messageText = NSLocalizedString("Wrong repeated password", comment: "")
alert.beginSheetModal(for: window) { (returnCode: NSApplication.ModalResponse) -> Void in }
return
}
if let encCompletionHandler = encCompletionHandler {
encCompletionHandler(passwordField.stringValue)
}
self.alert?.window.close()
}
private func masterPasswordPrompt(validation: Bool = false, completion: @escaping (String) -> ()) {
DispatchQueue.main.async {
guard var window = self.view.window else { return }
if NSApplication.shared.keyWindow?.contentViewController?.isKind(of: NoteViewController.self) == true,
let evc = NSApplication.shared.keyWindow?.contentViewController as? EditorViewController,
let currentWin = evc.view.window {
window = currentWin
}
self.alert = NSAlert()
guard let alert = self.alert else { return }
alert.alertStyle = .informational
if validation {
alert.messageText = NSLocalizedString("Enter an encryption password:", comment: "")
alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
alert.addButton(withTitle: NSLocalizedString("Cancel", comment: ""))
alert.buttons[0].target = self
alert.buttons[0].action = #selector(self.onOkClick(_:))
// Create the NSTextFields and labels
let newPasswordLabel = NSTextField(labelWithString: NSLocalizedString("Password:", comment: ""))
let newPasswordField = NSSecureTextField(frame: NSRect(x: 0, y: 0, width: 200, height: 24))
let repeatPasswordLabel = NSTextField(labelWithString: NSLocalizedString("Verify Password:", comment: ""))
let repeatPasswordField = NSSecureTextField(frame: NSRect(x: 0, y: 0, width: 200, height: 24))
self.encPassword = newPasswordField
self.encVerifyPassword = repeatPasswordField
self.encCompletionHandler = completion
newPasswordLabel.alignment = .right
repeatPasswordLabel.alignment = .right
// Add the labels and text fields to a custom view
let containerView = NSView(frame: NSRect(x: 0, y: 0, width: 400, height: 60))
containerView.translatesAutoresizingMaskIntoConstraints = false
newPasswordLabel.translatesAutoresizingMaskIntoConstraints = false
newPasswordField.translatesAutoresizingMaskIntoConstraints = false
repeatPasswordLabel.translatesAutoresizingMaskIntoConstraints = false
repeatPasswordField.translatesAutoresizingMaskIntoConstraints = false
containerView.addSubview(newPasswordLabel)
containerView.addSubview(newPasswordField)
containerView.addSubview(repeatPasswordLabel)
containerView.addSubview(repeatPasswordField)
// Set the custom view as the accessory view for the NSAlert
alert.accessoryView = containerView
// Define constraints
NSLayoutConstraint.activate([
newPasswordLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 8),
newPasswordLabel.topAnchor.constraint(equalTo: containerView.topAnchor, constant: 8),
newPasswordField.leadingAnchor.constraint(equalTo: newPasswordLabel.trailingAnchor, constant: 8),
newPasswordField.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: 0),
newPasswordField.widthAnchor.constraint(equalToConstant: 200),
newPasswordField.centerYAnchor.constraint(equalTo: newPasswordLabel.centerYAnchor),
repeatPasswordLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 8),
repeatPasswordLabel.topAnchor.constraint(equalTo: newPasswordLabel.bottomAnchor, constant: 8),
repeatPasswordField.leadingAnchor.constraint(equalTo: repeatPasswordLabel.trailingAnchor, constant: 8),
repeatPasswordField.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: 0),
repeatPasswordField.widthAnchor.constraint(equalToConstant: 200),
repeatPasswordField.centerYAnchor.constraint(equalTo: repeatPasswordLabel.centerYAnchor),
containerView.widthAnchor.constraint(equalToConstant: 400),
containerView.heightAnchor.constraint(equalToConstant: 60),
])
// Show the NSAlert
alert.beginSheetModal(for: window) { (returnCode: NSApplication.ModalResponse) -> Void in
self.alert = nil
}
newPasswordField.becomeFirstResponder()
return
}
let field = NSSecureTextField(frame: NSRect(x: 0, y: 0, width: 290, height: 20))
alert.accessoryView = field
alert.messageText = NSLocalizedString("Master password:", comment: "")
alert.informativeText = NSLocalizedString("Please enter password for current note", comment: "")
alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
alert.addButton(withTitle: NSLocalizedString("Cancel", comment: ""))
alert.beginSheetModal(for: window) { (returnCode: NSApplication.ModalResponse) -> Void in
if returnCode == NSApplication.ModalResponse.alertFirstButtonReturn {
completion(field.stringValue)
}
self.alert = nil
}
field.becomeFirstResponder()
}
}
public func lockUnlocked(notes: [Note]) -> [Note] {
var notes = notes
var isFirst = true
for note in notes {
if note.isUnlocked() && note.isEncrypted() {
if note.lock() && isFirst {
reloadAllOpenedWindows(note: note)
}
removeTags(note: note)
notes.removeAll { $0 === note }
}
isFirst = false
ViewController.shared()?.notesTableView.reloadRow(note: note)
}
// Focus notes list if active main window
if let vc = view.window?.contentViewController as? ViewController, let mainWindow = view.window {
mainWindow.makeFirstResponder(vc.notesTableView)
}
return notes
}
public func decryptUnlocked(notes: [Note]) -> [Note] {
var notes = notes
for note in notes {
if note.isUnlocked() {
if note.unEncryptUnlocked() {
notes.removeAll { $0 === note }
ViewController.shared()?.notesTableView.reloadRow(note: note)
}
}
}
return notes
}
public func removeTags(note: Note) {
let tags = note.tags
note.tags = []
ViewController.shared()?.sidebarOutlineView?.removeTags(tags)
}
public func dropTitle() {
let appName = Bundle.main.object(forInfoDictionaryKey: "CFBundleDisplayName") as? String ?? "FSNotes"
vcTitleLabel?.stringValue = appName
view.window?.title = appName
}
func focusEditArea() {
guard let editor = vcEditor,
let note = editor.note,
!editor.isPreviewEnabled(),
note.container != .encryptedTextPack else { return }
editor.window?.makeFirstResponder(editor)
if let ntv = ViewController.shared()?.notesTableView, ntv.selectedRow > -1 {
vcEditor?.isEditable = true
vcNonSelectedLabel?.isHidden = true
}
}
// Changed main edit view
func textDidChange(_ notification: Notification) {
guard let editor = vcEditor,
let note = editor.note,
let vc = ViewController.shared() else { return }
vc.prevCommit = nil
if editor.isEditable {
note.isBlocked = true
editor.textStorage?.removeHighlight()
note.save(attributed: editor.attributedString())
updateLastEditedStatus()
vc.reSort(note: note)
}
breakUndoTimer.invalidate()
breakUndoTimer = Timer.scheduledTimer(timeInterval: 30, target: self, selector: #selector(breakUndo), userInfo: nil, repeats: true)
}
private func updateLastEditedStatus() {
let editors = AppDelegate.getEditTextViews()
for editor in editors {
editor.isLastEdited = false
}
vcEditor?.isLastEdited = true
}
@objc func breakUndo() {
guard let editor = vcEditor else { return }
if (
editor.isPreviewEnabled() == false
&& editor.isEditable
) {
editor.breakUndoCoalescing()
}
}
public func createNote(name: String = "", content: String = "", folderName: String? = nil, openInNewWindow: Bool = false) -> Note? {
guard let vc = ViewController.shared() else { return nil }
var text = String()
var project: Project?
if let folderName = folderName {
project = vc.sidebarOutlineView.getOrCreateProject(name: folderName)
if let existProject = project, existProject.isEncrypted {
project = nil
}
}
let selectedProjects = vc.sidebarOutlineView.getSidebarProjects()
var sidebarProject = project ?? selectedProjects?.first
if sidebarProject == nil {
sidebarProject = Storage.shared().getDefault()
}
guard let project = sidebarProject, !project.isLocked() else { return nil }
if !name.isEmpty, [.autoRename, .autoRenameNew].contains(UserDefaultsManagement.naming) && UserDefaultsManagement.autoInsertHeader {
text.append("# " + name + "\n\n")
}
if !content.isEmpty {
text.append(content)
}
let inlineTags = vc.sidebarOutlineView.getSelectedInlineTags()
if !inlineTags.isEmpty {
text.append(inlineTags)
}
if let type = vc.getSidebarType(), type == .Todo, content.count == 0 {
text = "- [ ] "
}
let note = Note(name: name, project: project)
note.content = NSMutableAttributedString(string: text)
if note.save() {
Storage.shared().add(note)
}
_ = note.scanContentTags()
if folderName == nil, let selectedProjects = selectedProjects, !selectedProjects.contains(project) {
return note
}
if !openInNewWindow {
disablePreview()
vc.notesTableView.deselectNotes()
vc.storage.searchQuery.dropFilter()
vc.editor.string = text
vc.editor.note = note
vc.search.stringValue.removeAll()
}
vc.updateTable() {
if openInNewWindow {
return
}
DispatchQueue.main.async {
vc.notesTableView.saveNavigationHistory(note: note)
if let index = vc.notesTableView.getIndex(for: note) {
vc.notesTableView.selectRowIndexes([index], byExtendingSelection: false)
vc.notesTableView.scrollRowToVisible(index)
}
vc.focusEditArea()
NSApp.activate(ignoringOtherApps: true)
self.view.window?.makeKeyAndOrderFront(self)
}
}
// Project encrypted and unlocked – encrypt by default
if let password = project.password {
if note.encrypt(password: password) {
if note.unLock(password: password) {
note.password = password
}
}
}
return note
}
}
================================================
FILE: FSNotes/Extensions/NSAppearance+.swift
================================================
//
// NSAppearance+.swift
// FSNotes
//
// Created by Oleksandr Glushchenko on 9/29/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import AppKit.NSAppearance
extension NSAppearance {
var isDark: Bool {
if UserDefaultsManagement.appearanceType == .System {
let mode = UserDefaults.standard.string(forKey: "AppleInterfaceStyle")
return mode == "Dark"
}
if self.name == .vibrantDark { return true }
guard #available(macOS 10.14, *) else { return false }
switch self.name {
case .accessibilityHighContrastDarkAqua,
.darkAqua,
.accessibilityHighContrastVibrantDark:
return true
default:
return false
}
}
}
================================================
FILE: FSNotes/Extensions/NSColor+.swift
================================================
//
// NSColor+.swift
// FSNotes
//
// Created by Олександр Глущенко on 11.08.2021.
// Copyright © 2021 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
public extension NSColor {
static var tagColor: NSColor {
get {
let accentColor = UserDefaults.standard.value(forKey: "AppleAccentColor")
if #available(macOS 10.14, *), accentColor != nil {
return NSColor.controlAccentColor
}
if #available(macOS 10.13, *) {
return NSColor(named: "background_tag")!
}
return NSColor.gray
}
}
var hexString: String {
guard let rgbColor = usingColorSpace(.deviceRGB) else {
return "#FFFFFF"
}
let red = Int(round(rgbColor.redComponent * 0xFF))
let green = Int(round(rgbColor.greenComponent * 0xFF))
let blue = Int(round(rgbColor.blueComponent * 0xFF))
let hexString = NSString(format: "#%02X%02X%02X", red, green, blue)
return hexString as String
}
}
================================================
FILE: FSNotes/Extensions/NSFont+.swift
================================================
//
// NSFont+.swift
// FSNotes
//
// Created by Oleksandr Glushchenko on 8/26/17.
// Copyright © 2017 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
extension NSFont {
public var lineHeight: CGFloat {
return CGFloat(ceilf(Float(ascender + abs(descender) + leading)))
}
public var lineHeightCustom: CGFloat {
return CGFloat(ceilf(Float(ascender + abs(descender) + leading)))
}
public func getAttachmentHeight() -> Double {
return Double(pointSize) + 6
}
var isBold: Bool {
return fontDescriptor.symbolicTraits.contains(.bold)
}
var isItalic: Bool {
return fontDescriptor.symbolicTraits.contains(.italic)
}
var height:CGFloat {
let constraintRect = CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude)
let boundingBox = "A".boundingRect(with: constraintRect, options: NSString.DrawingOptions.usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font: self], context: nil)
return boundingBox.height
}
static func italicFont() -> NSFont {
return NSFontManager().convert(UserDefaultsManagement.noteFont, toHaveTrait: .italicFontMask)
}
static func boldFont() -> NSFont {
return NSFontManager().convert(UserDefaultsManagement.noteFont, toHaveTrait: .boldFontMask)
}
func bold() -> NSFont {
guard let family = UserDefaultsManagement.noteFont.familyName else {
return UserDefaultsManagement.noteFont
}
var mask = 0
if (isItalic) {
mask = NSFontBoldTrait|NSFontItalicTrait
} else {
mask = NSFontBoldTrait
}
if let font = NSFontManager().font(withFamily: family, traits: NSFontTraitMask(rawValue: NSFontTraitMask.RawValue(mask)), weight: 5, size: CGFloat(UserDefaultsManagement.fontSize)) {
return font
}
return UserDefaultsManagement.noteFont
}
}
================================================
FILE: FSNotes/Extensions/NSImage+.swift
================================================
//
// NSImage+.swift
// FSNotesCore macOS
//
// Created by Oleksandr Glushchenko on 10/14/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
public extension NSImage {
var height: CGFloat {
return self.size.height
}
/// Returns the width of the current image.
var width: CGFloat {
return self.size.width
}
/// Returns a png representation of the current image.
var PNGRepresentation: Data? {
if let tiff = self.tiffRepresentation, let tiffData = NSBitmapImageRep(data: tiff) {
return tiffData.representation(using: .png, properties: [:])
}
return nil
}
/// Copies the current image and resizes it to the given size.
///
/// - parameter size: The size of the new image.
///
/// - returns: The resized copy of the given image.
func copy(size: NSSize) -> NSImage? {
// Create a new rect with given width and height
let frame = NSRect(x: 0, y: 0, width: size.width, height: size.height)
// Get the best representation for the given size.
guard let rep = self.bestRepresentation(for: frame, context: nil, hints: nil) else {
return nil
}
// Create an empty image with the given size.
let img = NSImage(size: size)
// Set the drawing context and make sure to remove the focus before returning.
img.lockFocus()
defer { img.unlockFocus() }
// Draw the new image
if rep.draw(in: frame) {
return img
}
// Return nil in case something went wrong.
return nil
}
/// Copies the current image and resizes it to the size of the given NSSize, while
/// maintaining the aspect ratio of the original image.
///
/// - parameter size: The size of the new image.
///
/// - returns: The resized copy of the given image.
func resizeWhileMaintainingAspectRatioToSize(size: NSSize) -> NSImage? {
let newSize: NSSize
let widthRatio = size.width / self.width
let heightRatio = size.height / self.height
if widthRatio > heightRatio {
newSize = NSSize(width: floor(self.width * widthRatio), height: floor(self.height * widthRatio))
} else {
newSize = NSSize(width: floor(self.width * heightRatio), height: floor(self.height * heightRatio))
}
return self.copy(size: newSize)
}
/// Copies and crops an image to the supplied size.
///
/// - parameter size: The size of the new image.
///
/// - returns: The cropped copy of the given image.
func crop(size: NSSize) -> NSImage? {
// Resize the current image, while preserving the aspect ratio.
guard let resized = self.resizeWhileMaintainingAspectRatioToSize(size: size) else {
return nil
}
// Get some points to center the cropping area.
let xCoord = floor((resized.width - size.width) / 2)
let yCoord = floor((resized.height - size.height) / 2)
// Create the cropping frame.
let frame = NSRect(x: xCoord, y: yCoord, width: size.width, height: size.height)
// Get the best representation of the image for the given cropping frame.
guard let rep = resized.bestRepresentation(for: frame, context: nil, hints: nil) else {
return nil
}
// Create a new image with the new size
let img = NSImage(size: size)
img.lockFocus()
defer { img.unlockFocus() }
if rep.draw(
in: NSRect(x: 0, y: 0, width: size.width, height: size.height),
from: frame,
operation: NSCompositingOperation.copy,
fraction: 1.0,
respectFlipped: false,
hints: [:]) {
// Return the cropped image.
return img
}
// Return nil in case anything fails.
return nil
}
/// Saves the PNG representation of the current image to the HD.
///
/// - parameter url: The location url to which to write the png file.
func savePNGRepresentationToURL(url: URL) throws {
if let png = self.PNGRepresentation {
try png.write(to: url, options: .atomicWrite)
}
}
func resize(to targetSize: CGSize) -> NSImage? {
let frame = CGRect(x: 0, y: 0, width: targetSize.width, height: targetSize.height)
guard let representation = bestRepresentation(for: frame, context: nil, hints: nil) else {
return nil
}
let image = NSImage(size: targetSize, flipped: false, drawingHandler: { (_) -> Bool in
return representation.draw(in: frame)
})
return image
}
func resized(to newSize: NSSize) -> NSImage? {
let scale = NSScreen.main?.backingScaleFactor ?? 1.0
let pixelWidth = Int(newSize.width * scale)
let pixelHeight = Int(newSize.height * scale)
if let bitmapRep = NSBitmapImageRep(
bitmapDataPlanes: nil,
pixelsWide: pixelWidth,
pixelsHigh: pixelHeight,
bitsPerSample: 8,
samplesPerPixel: 4,
hasAlpha: true,
isPlanar: false,
colorSpaceName: .calibratedRGB,
bytesPerRow: 0,
bitsPerPixel: 0
) {
bitmapRep.size = newSize
NSGraphicsContext.saveGraphicsState()
NSGraphicsContext.current = NSGraphicsContext(bitmapImageRep: bitmapRep)
let rect = NSRect(x: 0, y: 0, width: newSize.width, height: newSize.height)
draw(in: rect, from: .zero, operation: .copy, fraction: 1.0)
NSGraphicsContext.restoreGraphicsState()
let resizedImage = NSImage(size: newSize)
resizedImage.addRepresentation(bitmapRep)
return resizedImage
}
return nil
}
/// Copy the image and resize it to the supplied size, while maintaining it's
/// original aspect ratio.
///
/// - Parameter size: The target size of the image.
/// - Returns: The resized image.
func resizeMaintainingAspectRatio(to targetSize: CGSize) -> NSImage? {
let widthRatio = targetSize.width / size.width
let heightRatio = targetSize.height / size.height
let ratio = max(widthRatio, heightRatio)
let newSize = CGSize(width: floor(size.width * ratio), height: floor(size.height * ratio))
return resized(to: NSSize(width: newSize.width, height: newSize.height))
}
// MARK: Cropping
/// Resize the image, to nearly fit the supplied cropping size
/// and return a cropped copy the image.
///
/// - Parameter size: The size of the new image.
/// - Returns: The cropped image.
func crop(to targetSize: CGSize) -> NSImage? {
// Resize the current image, while preserving the aspect ratio.
guard let resized = resizeMaintainingAspectRatio(to: targetSize) else {
return nil
}
// Get some points to center the cropping area.
let yCoord = floor(resized.size.height - targetSize.height)
// Create the cropping frame.
let frame = CGRect(origin: CGPoint(x: 0, y: yCoord), size: targetSize)
// Get the best representation of the image for the given cropping frame.
guard let representation = resized.bestRepresentation(for: frame, context: nil, hints: nil) else {
return nil
}
// Create a new image with the new size
let cropped = NSImage(size: targetSize)
cropped.lockFocus()
defer { cropped.unlockFocus() }
let outputFrame = CGRect(origin: CGPoint(x: 0, y: 0), size: targetSize)
guard representation.draw(in: outputFrame, from: frame, operation: .copy, fraction: 1.0, respectFlipped: false, hints: [:]) else {
return nil
}
return cropped
}
var jpgData: Data? {
guard let tiffRepresentation = tiffRepresentation,
let bitmapImage = NSBitmapImageRep(data: tiffRepresentation)
else { return nil }
return bitmapImage.representation(using: .jpeg, properties: [:])
}
func tint(color: NSColor) -> NSImage {
if let image = self.copy() as? NSImage {
image.lockFocus()
color.set()
let imageRect = NSRect(origin: .zero, size: image.size)
imageRect.fill(using: .sourceAtop)
image.unlockFocus()
return image
}
return self
}
func roundCorners(withRadius radius: CGFloat) -> NSImage {
let rect = NSRect(origin: NSPoint.zero, size: size)
if
let cgImage = self.cgImage,
let context = CGContext(data: nil,
width: Int(size.width),
height: Int(size.height),
bitsPerComponent: 8,
bytesPerRow: 4 * Int(size.width),
space: CGColorSpaceCreateDeviceRGB(),
bitmapInfo: CGImageAlphaInfo.premultipliedFirst.rawValue) {
context.beginPath()
context.addPath(CGPath(roundedRect: rect, cornerWidth: radius, cornerHeight: radius, transform: nil))
context.closePath()
context.clip()
context.draw(cgImage, in: rect)
if let composedImage = context.makeImage() {
return NSImage(cgImage: composedImage, size: size)
}
}
return self
}
var cgImage: CGImage? {
var rect = CGRect.init(origin: .zero, size: self.size)
return self.cgImage(forProposedRect: &rect, context: nil, hints: nil)
}
}
================================================
FILE: FSNotes/Extensions/NSWindow+.swift
================================================
//
// NSWindow+.swift
// FSNotes
//
// Created by Oleksandr Hlushchenko on 10.07.2022.
// Copyright © 2022 Oleksandr Hlushchenko. All rights reserved.
//
import Cocoa
extension NSWindow {
public func setFrameOriginToPositionWindowInCenterOfScreen() {
if let screenSize = screen?.frame.size {
let origin = NSPoint(x: (screenSize.width-800)/2, y: (screenSize.height-600)/2)
self.setFrame(NSRect(origin: origin, size: CGSize(width: 800, height: 600)), display: true)
}
}
}
================================================
FILE: FSNotes/Extensions/UserDefaultsManagement+.swift
================================================
//
// UserDefaultsManagement+.swift
// FSNotesCore macOS
//
// Created by Oleksandr Glushchenko on 10/25/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import Foundation
import MASShortcut
import AppKit
extension UserDefaultsManagement {
private struct Constants {
static let ActivateKeyCode = "activateKeyCode"
static let ActivateKeyModifier = "activateKeyModifier"
static let AppearanceTypeKey = "appearanceType2025"
static let codeTheme = "codeTheme"
static let codeThemeDark = "codeThemeDark"
static let darkMode = "darkMode"
static let dockIcon = "dockIcon"
static let NewNoteKeyModifier = "newNoteKeyModifier"
static let NewNoteKeyCode = "newNoteKeyCode"
static let SearchNoteKeyCode = "searchNoteKeyCode"
static let SearchNoteKeyModifier = "searchNoteKeyModifier"
static let ProjectsKey = "projects"
static let QuickNoteKey = "quickNoteKey"
static let QuickNoteKeyModifier = "quickNoteKeyModifier"
}
static var appearanceType: AppearanceType {
get {
if let result = UserDefaults.standard.object(forKey: Constants.AppearanceTypeKey) as? Int {
return AppearanceType(rawValue: result)!
}
return AppearanceType.System
}
set {
UserDefaults.standard.set(newValue.rawValue, forKey: Constants.AppearanceTypeKey)
}
}
static var newNoteShortcut: MASShortcut? {
get {
let code = UserDefaults.standard.object(forKey: Constants.NewNoteKeyCode)
let modifier = UserDefaults.standard.object(forKey: Constants.NewNoteKeyModifier)
if code != nil && modifier != nil, let keyCode = code as? UInt, let modifierFlags = modifier as? UInt {
if (code as? Int) == 0 && (modifier as? Int) == 0 {
return nil
}
return MASShortcut(keyCode: keyCode, modifierFlags: modifierFlags)
}
return MASShortcut(keyCode: 45, modifierFlags: 917504)
}
set {
let code = newValue?.keyCode ?? 0
let modifier = newValue?.modifierFlags ?? 0
UserDefaults.standard.set(code, forKey: Constants.NewNoteKeyCode)
UserDefaults.standard.set(modifier, forKey: Constants.NewNoteKeyModifier)
}
}
static var quickNoteShortcut: MASShortcut? {
get {
let code = UserDefaults.standard.object(forKey: Constants.QuickNoteKey)
let modifier = UserDefaults.standard.object(forKey: Constants.QuickNoteKeyModifier)
if code != nil && modifier != nil, let keyCode = code as? UInt, let modifierFlags = modifier as? UInt {
if (code as? Int) == 0 && (modifier as? Int) == 0 {
return nil
}
return MASShortcut(keyCode: keyCode, modifierFlags: modifierFlags)
}
return MASShortcut(keyCode: 31, modifierFlags: 917504)
}
set {
let code = newValue?.keyCode ?? 0
let modifier = newValue?.modifierFlags ?? 0
UserDefaults.standard.set(code, forKey: Constants.QuickNoteKey)
UserDefaults.standard.set(modifier, forKey: Constants.QuickNoteKeyModifier)
}
}
static var searchNoteShortcut: MASShortcut? {
get {
let code = UserDefaults.standard.object(forKey: Constants.SearchNoteKeyCode)
let modifier = UserDefaults.standard.object(forKey: Constants.SearchNoteKeyModifier)
if code != nil && modifier != nil, let keyCode = code as? UInt, let modifierFlags = modifier as? UInt {
if (code as? Int) == 0 && (modifier as? Int) == 0 {
return nil
}
return MASShortcut(keyCode: keyCode, modifierFlags: modifierFlags)
}
return MASShortcut(keyCode: 37, modifierFlags: 917504)
}
set {
let code = newValue?.keyCode ?? 0
let modifier = newValue?.modifierFlags ?? 0
UserDefaults.standard.set(code, forKey: Constants.SearchNoteKeyCode)
UserDefaults.standard.set(modifier, forKey: Constants.SearchNoteKeyModifier)
}
}
static var activateShortcut: MASShortcut? {
get {
let code = UserDefaults.standard.object(forKey: Constants.ActivateKeyCode)
let modifier = UserDefaults.standard.object(forKey: Constants.ActivateKeyModifier)
if code != nil && modifier != nil, let keyCode = code as? UInt, let modifierFlags = modifier as? UInt {
if (code as? Int) == 0 && (modifier as? Int) == 0 {
return nil
}
return MASShortcut(keyCode: keyCode, modifierFlags: modifierFlags)
}
return MASShortcut(keyCode: 40, modifierFlags: 917504)
}
set {
let code = newValue?.keyCode ?? 0
let modifier = newValue?.modifierFlags ?? 0
UserDefaults.standard.set(code, forKey: Constants.ActivateKeyCode)
UserDefaults.standard.set(modifier, forKey: Constants.ActivateKeyModifier)
}
}
static var dockIcon: Int {
get {
if let tag = UserDefaults.standard.object(forKey: Constants.dockIcon) as? Int {
return tag
}
return 0
}
set {
UserDefaults.standard.set(newValue, forKey: Constants.dockIcon)
}
}
static var noteFont: NSFont {
get {
if let name = fontName, name.starts(with: ".") {
return NSFont.systemFont(ofSize: CGFloat(self.fontSize))
}
if let fontName = self.fontName, let font = NSFont(name: fontName, size: CGFloat(self.fontSize)) {
return font
}
return NSFont.systemFont(ofSize: CGFloat(self.fontSize))
}
set {
self.fontName = newValue.fontName
self.fontSize = Int(newValue.pointSize)
}
}
static var codeFont: NSFont {
get {
if let font = NSFont(name: self.codeFontName, size: CGFloat(self.codeFontSize)) {
return font
}
return NSFont.systemFont(ofSize: CGFloat(self.codeFontSize))
}
set {
self.codeFontName = newValue.familyName ?? "Source Code Pro"
self.codeFontSize = Int(newValue.pointSize)
}
}
}
================================================
FILE: FSNotes/FSNotes (CloudKit).entitlements
================================================
com.apple.developer.aps-environment
development
com.apple.developer.icloud-container-environment
Production
com.apple.developer.icloud-container-identifiers
iCloud.co.fluder.fsnotes
com.apple.developer.icloud-services
CloudDocuments
com.apple.developer.ubiquity-container-identifiers
iCloud.co.fluder.fsnotes
com.apple.developer.ubiquity-kvstore-identifier
$(TeamIdentifierPrefix)co.fluder.fsnotes
com.apple.security.app-sandbox
com.apple.security.files.user-selected.read-write
com.apple.security.network.client
com.apple.security.print
================================================
FILE: FSNotes/FSNotes.entitlements
================================================
com.apple.security.app-sandbox
com.apple.security.files.user-selected.read-write
com.apple.security.network.client
com.apple.security.print
================================================
FILE: FSNotes/Helpers/FSNTextAttachmentCell.swift
================================================
//
// FSNTextAttahcmentCell.swift
// FSNotes
//
// Created by Олександр Глущенко on 25.11.2020.
// Copyright © 2020 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
class FSNTextAttachmentCell: NSTextAttachmentCell {
let textContainer: NSTextContainer
init(textContainer: NSTextContainer, image: NSImage) {
self.textContainer = textContainer
super.init(imageCell: image)
}
required init(coder: NSCoder) {
self.textContainer = NSTextContainer()
super.init(coder: coder)
}
override func cellSize() -> NSSize {
let size = super.cellSize()
if size.height == UserDefaultsManagement.noteFont.getAttachmentHeight() {
return size
}
return NSSize(width: textContainer.size.width, height: size.height)
}
override nonisolated func cellBaselineOffset() -> NSPoint {
return NSPoint(x: 0, y: -2)
}
}
================================================
FILE: FSNotes/Helpers/FileSystemEventManager.swift
================================================
//
// FileSystemEventManager.swift
// FSNotes
//
// Created by Oleksandr Glushchenko on 7/13/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import Foundation
class FileSystemEventManager {
private var storage: Storage
private var delegate: ViewController
private var watcher: FileWatcher?
private var observedFolders: [String]
private var textBundleItems = ["text.markdown", "text.md", "text.txt", "info.json"]
init(storage: Storage, delegate: ViewController) {
self.storage = storage
self.delegate = delegate
self.observedFolders = self.storage.getProjectPaths()
}
public func start() {
watcher = FileWatcher(self.observedFolders)
watcher?.callback = { event in
guard let path = event.path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else {
return
}
guard let url = URL(string: "file://" + path) else {
return
}
if !event.path.contains(".textbundle") && (
event.dirRemoved
|| event.dirCreated
|| event.dirRenamed
|| event.dirChange
) {
self.handleDirEvents(event: event)
return
}
if url.lastPathComponent == ".encrypt" {
self.loadEncryptionStatus(url: url)
return
}
if !self.storage.isValidNote(url: url) {
return
}
if event.fileRemoved || event.dirRemoved {
guard let note = self.storage.getBy(url: url) else { return }
self.removeNote(note: note)
}
let fullUrl = self.handleTextBundle(url: url)
// Resolve conflicts if exist
if UserDefaultsManagement.automaticConflictsResolution, let note = self.storage.getBy(url: fullUrl) {
self.resolveConflict(url: note.url)
}
if event.fileRenamed || event.dirRenamed {
self.moveHandler(url: fullUrl, pathList: self.observedFolders)
return
}
guard self.checkFile(url: fullUrl, pathList: self.observedFolders) else { return }
// Order is important, invoke only before change
if event.fileCreated {
self.importNote(fullUrl)
return
}
if event.fileChange || event.dirChange, let note = self.storage.getBy(url: fullUrl) {
self.reloadNote(note: note)
}
}
watcher?.start()
}
private func handleDirEvents(event: FileWatcherEvent) {
guard !event.path.contains("Trash") else { return }
let dirURL = URL(fileURLWithPath: event.path, isDirectory: true)
let project = self.storage.getProjectBy(url: dirURL)
if dirURL.path.contains("/.") {
return
}
guard !dirURL.isHidden() else {
// hide if exist and hidden (xattr "es.fsnot.hidden.dir")
if event.dirChange {
if let project = project {
OperationQueue.main.addOperation {
self.delegate.sidebarOutlineView.removeRows(projects: [project])
}
}
}
return
}
if event.dirRenamed {
if let project = project {
// hack: occasionally get rename event when created
if !FileManager.default.fileExists(atPath: dirURL.path) {
OperationQueue.main.addOperation {
self.delegate.sidebarOutlineView.removeRows(projects: [project])
}
}
} else {
if FileManager.default.directoryExists(atUrl: dirURL) {
OperationQueue.main.addOperation {
if let projects = self.storage.insert(url: dirURL) {
self.delegate.sidebarOutlineView.insertRows(projects: projects)
}
}
}
}
return
}
if event.dirRemoved {
if let project = project {
OperationQueue.main.addOperation {
self.delegate.sidebarOutlineView.removeRows(projects: [project])
}
}
return
}
// dirChange on xattr "es.fsnot.hidden.dir" changed
if event.dirCreated || (
event.dirChange && dirURL.hasNonHiddenBit()
) {
OperationQueue.main.addOperation {
if let projects = self.storage.insert(url: dirURL) {
self.delegate.sidebarOutlineView.insertRows(projects: projects)
}
}
return
}
}
private func moveHandler(url: URL, pathList: [String]) {
let fileExistInFS = self.checkFile(url: url, pathList: pathList)
guard let note = self.storage.getBy(url: url) else {
if fileExistInFS {
self.importNote(url)
}
return
}
if fileExistInFS {
renameNote(note: note)
return
}
removeNote(note: note)
}
private func checkFile(url: URL, pathList: [String]) -> Bool {
return (
FileManager.default.fileExists(atPath: url.path)
&& self.storage.isValidNote(url: url)
&& pathList.contains(url.deletingLastPathComponent().path)
)
}
private func importNote(_ url: URL) {
let url = self.handleTextBundle(url: url)
let n = storage.getBy(url: url)
guard n == nil else {
if let nUnwrapped = n, nUnwrapped.url == UserDataService.instance.focusOnImport {
self.delegate.updateTable() {
self.delegate.notesTableView.setSelected(note: nUnwrapped)
UserDataService.instance.focusOnImport = nil
}
// When git checkout .textbundle/text.md system trigger remove/create events
// but the note is not deleted, so the note must be reloaded
} else if let nUnwrapped = n {
reloadNote(note: nUnwrapped)
}
return
}
guard let note = storage.importNote(url: url) else { return }
DispatchQueue.main.async {
if let url = UserDataService.instance.focusOnImport,
let note = self.storage.getBy(url: url)
{
self.delegate.updateTable() {
self.delegate.notesTableView.setSelected(note: note)
UserDataService.instance.focusOnImport = nil
}
} else {
if !note.isTrash() {
OperationQueue.main.addOperation {
self.delegate.notesTableView.insertRows(notes: [note])
}
}
}
}
}
private func renameNote(note: Note) {
if note.url == UserDataService.instance.focusOnImport {
self.delegate.updateTable() {
self.delegate.notesTableView.setSelected(note: note)
UserDataService.instance.focusOnImport = nil
}
// On TextBundle import
} else {
self.reloadNote(note: note)
}
}
private func removeNote(note: Note) {
print("FSWatcher remove note: \"\(note.name)\"")
self.storage.removeNotes(notes: [note], fsRemove: false) { _ in
DispatchQueue.main.async {
if self.delegate.notesTableView.numberOfRows > 0 {
self.delegate.notesTableView.removeRows(notes: [note])
}
}
}
}
private func reloadNote(note: Note) {
guard !note.isBlocked, note.container != .encryptedTextPack else {
return
}
guard let modificationDate = note.getFileModifiedDate(),
let creationDate = note.getFileCreationDate() else { return }
if modificationDate.isGreaterThan(note.modifiedLocalAt) {
note.modifiedLocalAt = modificationDate
note.cacheHash = nil
guard var fsContent = note.getContent() else { return }
_ = fsContent.loadAttachments(note)
// Trying load content from encrypted note with current password
if note.url.pathExtension == "etp", let password = note.password, note.unLock(password: password) {
fsContent = note.content
}
note.content = fsContent
// tags changes
let result = note.scanContentTags()
if result.0.count > 0 {
DispatchQueue.main.async {
self.delegate.sidebarOutlineView.insertTags(note: note)
}
}
if result.1.count > 0 {
DispatchQueue.main.async {
self.delegate.sidebarOutlineView.removeTags(result.1)
}
}
// reload view
self.delegate.notesTableView.reloadRow(note: note)
self.delegate.reSort(note: note)
let editors = AppDelegate.getEditTextViews()
for editor in editors {
if editor.note == note {
DispatchQueue.main.async {
editor.editorViewController?.refillEditArea(force: true)
}
}
}
}
if creationDate != note.creationDate {
note.creationDate = creationDate
delegate.notesTableView.reloadDate(note: note)
delegate.reSort(note: note)
// Reload images if note moved (cache invalidated)
note.loadPreviewInfo()
}
}
private func handleTextBundle(url: URL) -> URL {
if self.textBundleItems.contains(url.lastPathComponent) &&
url.path.contains(".textbundle") {
let path = url.deletingLastPathComponent().path
return URL(fileURLWithPath: path, isDirectory: false)
}
return url
}
public func restart() {
watcher?.stop()
self.observedFolders = self.storage.getProjectPaths()
start()
}
public func reloadObservedFolders() {
self.observedFolders = self.storage.getProjectPaths()
}
public func resolveConflict(url: URL) {
if let conflicts = NSFileVersion.unresolvedConflictVersionsOfItem(at: url as URL) {
for conflict in conflicts {
guard let modificationDate = conflict.modificationDate else {
continue
}
guard let localizedName = conflict.localizedName else {
continue
}
let localizedUrl = URL(fileURLWithPath: localizedName)
let ext = url.pathExtension
let name = localizedUrl.deletingPathExtension().lastPathComponent
let dateFormatter = ISO8601DateFormatter()
dateFormatter.formatOptions = [
.withYear,
.withMonth,
.withDay,
.withTime
]
let dateString: String = dateFormatter.string(from: modificationDate)
let conflictName = "\(name) (CONFLICT \(dateString)).\(ext)"
let to = url.deletingLastPathComponent().appendingPathComponent(conflictName)
if FileManager.default.fileExists(atPath: to.path) {
conflict.isResolved = true
continue
}
// Reload current encrypted note
let editors = AppDelegate.getEditTextViews()
for editor in editors {
if let currentNote = editor.note, currentNote.url == url {
if let password = currentNote.password, ext == "etp" {
_ = currentNote.unLock(password: password)
}
DispatchQueue.main.async {
editor.editorViewController?.refillEditArea(force: true)
}
}
}
do {
try FileManager.default.copyItem(at: conflict.url, to: to)
var attributes = [FileAttributeKey : Any]()
attributes[.posixPermissions] = 0o777
try FileManager.default.setAttributes(attributes, ofItemAtPath: to.path)
} catch let error {
print("Conflict resolving error: ", error)
}
conflict.isResolved = true
}
}
}
private func loadEncryptionStatus(url: URL) {
guard let project = self.storage.getProjectBy(url: url.deletingLastPathComponent()) else { return }
let state = project.isEncrypted
project.isEncrypted = FileManager.default.fileExists(atPath: url.path)
DispatchQueue.main.async {
if state && !project.isEncrypted {
project.password = nil
}
guard let selectedProject = self.delegate.sidebarOutlineView.getSelectedProject() else { return }
self.delegate.sidebarOutlineView.reloadItem(project)
// Selected at this moment
if selectedProject.url.path == project.url.path {
if project.isEncrypted && project.isLocked() {
self.delegate.notesTableView.enableLockedProject()
self.delegate.editor.clear()
} else {
self.delegate.notesTableView.disableLockedProject()
}
self.delegate.updateTable()
}
}
}
}
================================================
FILE: FSNotes/Helpers/FileWatcher.swift
================================================
import Cocoa
class FileWatcher{
let filePaths: [String] // -- paths to watch - works on folders and file paths
var callback : ((_ fileWatcherEvent:FileWatcherEvent) -> Void)?
var queue : DispatchQueue?
private var streamRef : FSEventStreamRef?
private var hasStarted : Bool { return streamRef != nil }
init(_ paths:[String]) { self.filePaths = paths }
/**
* Start listening for FSEvents
*/
func start() {
guard !hasStarted else { return } // -- make sure we are not already listening!
var context = FSEventStreamContext(
version: 0, info: Unmanaged.passUnretained(self).toOpaque(),
retain: retainCallback, release: releaseCallback,
copyDescription:nil
)
streamRef = FSEventStreamCreate(
kCFAllocatorDefault, eventCallback, &context,
filePaths as CFArray,FSEventStreamEventId(kFSEventStreamEventIdSinceNow), 0,
UInt32(kFSEventStreamCreateFlagUseCFTypes | kFSEventStreamCreateFlagFileEvents)
)
selectStreamScheduler()
FSEventStreamStart(streamRef!)
}
/**
* Stop listening for FSEvents
*/
func stop() {
guard hasStarted else { return } // -- make sure we are indeed listening!
FSEventStreamStop(streamRef!)
FSEventStreamInvalidate(streamRef!)
FSEventStreamRelease(streamRef!)
streamRef = nil
}
private let eventCallback:FSEventStreamCallback = {(
streamRef, clientCallBackInfo, numEvents, eventPaths, eventFlags, eventIds
) in
let fileSystemWatcher = Unmanaged.fromOpaque(clientCallBackInfo!).takeUnretainedValue()
let paths = Unmanaged.fromOpaque(eventPaths).takeUnretainedValue() as! [String]
for index in 0...fromOpaque(info!).retain()
return info
}
private let releaseCallback:CFAllocatorReleaseCallBack = {(info:UnsafeRawPointer?) in
Unmanaged.fromOpaque(info!).release()
}
private func selectStreamScheduler() {
guard let streamRef = streamRef else { return }
if let queue = queue {
FSEventStreamSetDispatchQueue(streamRef, queue)
} else {
FSEventStreamScheduleWithRunLoop(
streamRef, CFRunLoopGetMain(), CFRunLoopMode.defaultMode.rawValue
)
}
}
}
extension FileWatcher {
convenience init(_ paths:[String], _ callback: @escaping ((_ fileWatcherEvent:FileWatcherEvent) -> Void)) {
self.init(paths)
self.callback = callback
}
}
================================================
FILE: FSNotes/Helpers/FileWatcherEvent.swift
================================================
import Foundation
/**
* PARAM: id: is an id number that the os uses to differentiate between events.
* PARAM: path: is the path the change took place. its formated like so: Users/John/Desktop/test/text.txt
* PARAM: flag: pertains to the file event type.
* EXAMPLE: let url = NSURL(fileURLWithPath: event.path)//<--formats paths to: file:///Users/John/Desktop/test/text.txt
* EXAMPLE: Swift.print("fileWatcherEvent.fileChange: " + "\(event.fileChange)")
* EXAMPLE: Swift.print("fileWatcherEvent.fileModified: " + "\(event.fileModified)")
* EXAMPLE: Swift.print("\t eventId: \(event.id) - eventFlags: \(event.flags) - eventPath: \(event.path)")
*/
class FileWatcherEvent{
var id:FSEventStreamEventId
var path:String
var flags: FSEventStreamEventFlags
init(_ eventId:FSEventStreamEventId, _ eventPath: String, _ eventFlags: FSEventStreamEventFlags){
self.id = eventId
self.path = eventPath
self.flags = eventFlags
}
}
/**
* The following code is to differentiate between the FSEvent flag types (aka file event types)
* NOTE: Be aware that .DS_STORE changes frequently when other files change
*/
extension FileWatcherEvent{
/*general*/
var fileChange:Bool {return (flags & FSEventStreamEventFlags(kFSEventStreamEventFlagItemIsFile)) != 0}
var dirChange:Bool {return (flags & FSEventStreamEventFlags(kFSEventStreamEventFlagItemIsDir)) != 0}
/*CRUD*/
var created:Bool {return (flags & FSEventStreamEventFlags(kFSEventStreamEventFlagItemCreated)) != 0}
var removed:Bool {return (flags & FSEventStreamEventFlags(kFSEventStreamEventFlagItemRemoved)) != 0}
var renamed:Bool {return (flags & FSEventStreamEventFlags(kFSEventStreamEventFlagItemRenamed)) != 0}
var modified:Bool {return (flags & FSEventStreamEventFlags(kFSEventStreamEventFlagItemModified)) != 0}
}
/**
* Convenince
*/
extension FileWatcherEvent{
/*File*/
var fileCreated:Bool {return fileChange && created}
var fileRemoved:Bool {return fileChange && removed}
var fileRenamed:Bool {return fileChange && renamed}
var fileModified:Bool {return fileChange && modified}
/*Directory*/
var dirCreated:Bool {return dirChange && created}
var dirRemoved:Bool {return dirChange && removed}
var dirRenamed:Bool {return dirChange && renamed}
var dirModified:Bool {return dirChange && modified}
}
/**
* Simplifies debugging
* EXAMPLE: Swift.print(event.description)//Outputs: The file /Users/John/Desktop/test/text.txt was modified
*/
extension FileWatcherEvent{
var description:String {
var result = "The \(fileChange ? "file":"directory") \(self.path) was"
if self.created {
result += " created"
}
if self.removed {
result += " removed"
}
if self.renamed {
result += " renamed"
}
if self.modified {
result += " modified"
}
return result
}
}
================================================
FILE: FSNotes/Helpers/Printer.swift
================================================
//
// Printer.swift
// FSNotes
//
// Created by Oleksandr Hlushchenko on 08.08.2024.
// Copyright © 2024 Oleksandr Hlushchenko. All rights reserved.
//
import WebKit
@available(macOS 11.0, *)
class Printer: NSObject, WKNavigationDelegate, WKScriptMessageHandler {
private var indexURL: URL
private var pop: NSPrintOperation?
private var webView: WKWebView?
init(indexURL: URL) {
self.indexURL = indexURL
super.init()
}
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
guard message.name == "contentLoaded" else { return }
let printInfo = NSPrintInfo(dictionary: [.paperSize: CGSize(width: 595.28, height: 841.89)])
printInfo.horizontalPagination = .automatic
printInfo.verticalPagination = .automatic
let margin = 20.0
printInfo.leftMargin = margin
printInfo.topMargin = margin
printInfo.rightMargin = margin
printInfo.bottomMargin = margin
printInfo.isVerticallyCentered = true
printInfo.isHorizontallyCentered = true
self.pop = self.webView?.printOperation(with: printInfo)
self.pop?.printPanel.options.insert(.showsPaperSize)
self.pop?.printPanel.options.insert(.showsOrientation)
self.pop?.printPanel.options.insert(.showsPreview)
self.pop?.showsPrintPanel = true
self.pop?.showsProgressPanel = true
self.pop?.view?.frame = NSRect(x: 0, y: 0, width: 800.0, height: 500.0)
DispatchQueue.main.async {
let window = NSApplication.shared.mainWindow
//let window = NSWindow(contentRect: .zero, styleMask: .borderless, backing: .buffered, defer: false)
self.pop?.runModal(for: window!, delegate: nil, didRun: nil, contextInfo: nil)
}
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
let checkContentLoadedScript = """
function checkIfComplete() {
if (document.readyState === 'complete') {
window.webkit.messageHandlers.contentLoaded.postMessage("contentLoaded");
} else {
setTimeout(checkIfComplete, 100);
}
}
checkIfComplete();
"""
webView.evaluateJavaScript(checkContentLoadedScript, completionHandler: nil)
}
public func printWeb() {
let contentController = WKUserContentController()
contentController.add(self, name: "contentLoaded")
let config = WKWebViewConfiguration()
config.userContentController = contentController
webView = WKWebView(frame: NSRect(x: 0, y: 0, width: 595, height: 842), configuration: config)
webView?.navigationDelegate = self
let accessURL = indexURL.deletingLastPathComponent()
webView?.loadFileURL(indexURL, allowingReadAccessTo: accessURL)
}
}
================================================
FILE: FSNotes/Helpers/PrinterLegacy.swift
================================================
//
// PrinterLegacy.swift
// FSNotes
//
// Created by Oleksandr Hlushchenko on 08.08.2024.
// Copyright © 2024 Oleksandr Hlushchenko. All rights reserved.
//
import WebKit
@available(*, deprecated, message: "Remove after macOS 10.15 is no longer supported")
class PrinterLegacy: NSObject, WebFrameLoadDelegate {
private var indexURL: URL
private var pop: NSPrintOperation?
public var printWebView = WebView()
init(indexURL: URL) {
self.indexURL = indexURL
super.init()
}
func webView(_ sender: WebView!, didFinishLoadFor frame: WebFrame!) {
if sender.isLoading {
return
}
if frame != sender.mainFrame {
return
}
if sender.stringByEvaluatingJavaScript(from: "document.readyState") == "complete" {
sender.frameLoadDelegate = nil
let printInfo = NSPrintInfo.shared
printInfo.paperSize = NSMakeSize(595.22, 841.85)
printInfo.topMargin = 40.0
printInfo.leftMargin = 40.0
printInfo.rightMargin = 40.0
printInfo.bottomMargin = 40.0
let when = DispatchTime.now() + 0.2
DispatchQueue.main.asyncAfter(deadline: when) {
let operation: NSPrintOperation = NSPrintOperation(view: sender.mainFrame.frameView.documentView, printInfo: printInfo)
operation.printPanel.options.insert(NSPrintPanel.Options.showsPaperSize)
operation.printPanel.options.insert(NSPrintPanel.Options.showsOrientation)
operation.run()
}
}
}
public func printWeb() {
let printDir = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("Print")
guard let content = try? String(contentsOf: indexURL) else { return }
self.printWebView.frameLoadDelegate = self
self.printWebView.frame = NSRect(x: 0, y: 0, width: 800.0, height: 500.0)
self.printWebView.mainFrame.loadHTMLString(content, baseURL: printDir)
}
}
================================================
FILE: FSNotes/Helpers/SandboxBookmark.swift
================================================
//
// SandboxBookmark.swift
// FSNotes
//
// Created by Oleksandr Glushchenko on 8/6/17.
// Copyright © 2017 Oleksandr Glushchenko. All rights reserved.
//
import Foundation
class SandboxBookmark {
static var instance: SandboxBookmark? = nil
var bookmarks = [URL: Data]()
var successfullyRestored = [URL]()
public static func sharedInstance() -> SandboxBookmark {
guard let sandbox = self.instance else {
self.instance = SandboxBookmark()
return self.instance!
}
return sandbox
}
public func resetBookmarksDb() {
if let url = bookmark() {
try? FileManager.default.removeItem(at: url)
}
}
func bookmark() -> URL? {
if var url = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first {
url = url.appendingPathComponent("Bookmarks.dict")
return url
}
return nil
}
func load() {
guard let url = bookmark() else { return }
if FileManager.default.fileExists(atPath: url.path),
let data = try? Data(contentsOf: url) {
do {
if let bookmarks = try NSKeyedUnarchiver.unarchivedObject(ofClasses: [NSDictionary.self, NSURL.self, NSData.self], from: data) as? [URL: Data] {
self.bookmarks = bookmarks
for bookmark in bookmarks {
_ = restore(bookmark)
}
}
} catch {
print("Failed to unarchive bookmarks: \(error.localizedDescription)")
}
}
}
func save() {
guard let fileURL = bookmark() else { return }
do {
let data = try NSKeyedArchiver.archivedData(withRootObject: bookmarks, requiringSecureCoding: false)
try data.write(to: fileURL)
} catch {
print("Failed to save bookmarks: \(error.localizedDescription)")
}
}
func store(url: URL) {
#if os(OSX)
do {
let data = try url.bookmarkData(options: NSURL.BookmarkCreationOptions.withSecurityScope, includingResourceValuesForKeys: nil, relativeTo: nil)
bookmarks[url] = data
} catch {
Swift.print(error)
Swift.print("Error storing bookmarks")
}
#endif
}
func restore(_ bookmark: (key: URL, value: Data)) -> Bool {
#if os(OSX)
let restoredUrl: URL?
var isStale = false
do {
restoredUrl = try URL.init(resolvingBookmarkData: bookmark.value, options: NSURL.BookmarkResolutionOptions.withSecurityScope, relativeTo: nil, bookmarkDataIsStale: &isStale)
} catch {
Swift.print("Error restoring bookmarks: \(error)")
restoredUrl = nil
remove(url: bookmark.key)
save()
}
guard let url = restoredUrl else { return false }
if isStale {
Swift.print("URL is stale: \(url)")
return false
}
if url.startAccessingSecurityScopedResource() {
print("Bookmark restored: \(url.path)")
successfullyRestored.append(url)
return true
}
Swift.print("Couldn't access: \(url.path)")
#endif
return false
}
func remove(url: URL) {
bookmarks.removeValue(forKey: url)
}
func removeBy(_ url: URL) {
load()
bookmarks.removeValue(forKey: url)
save()
}
func rename(url: URL, new: URL) {
let value = bookmarks[url]
bookmarks[new] = value
save()
}
public func save(url: URL) {
guard let fileURL = bookmark() else { return }
if self.bookmarks.isEmpty,
FileManager.default.fileExists(atPath: fileURL.path),
let data = try? Data(contentsOf: fileURL) {
do {
if let bookmarks = try NSKeyedUnarchiver.unarchivedObject(ofClasses: [NSDictionary.self, NSURL.self, NSData.self], from: data) as? [URL: Data] {
self.bookmarks = bookmarks
}
} catch {
print("Failed to unarchive bookmarks: \(error.localizedDescription)")
}
}
self.store(url: url)
self.save()
}
public func getRestoredUrls() -> [URL] {
if successfullyRestored.isEmpty {
load()
}
return successfullyRestored
}
}
================================================
FILE: FSNotes/Helpers/Sidebar.swift
================================================
//
// Sidebar.swift
// FSNotes
//
// Created by Oleksandr Glushchenko on 4/7/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
typealias Image = NSImage
class Sidebar {
var list = [Any]()
let storage = Storage.shared()
public var items = [[SidebarItem]]()
init() {
guard let defaultURL = Storage.shared().getDefault()?.url else { return }
var system = [SidebarItem]()
if UserDefaultsManagement.sidebarVisibilityNotes {
// Notes
guard let defaultURL = Storage.shared().getDefault()?.url else { return }
let notesUrl = defaultURL.appendingPathComponent("Fake Virtual Notes Dir")
let notesLabel = NSLocalizedString("Notes", comment: "")
let fakeNotesProject =
Project(
storage: Storage.shared(),
url: notesUrl,
label: notesLabel,
isVirtual: true
)
let notes = SidebarItem(name: NSLocalizedString("Notes", comment: ""), project: fakeNotesProject, type: .All)
system.append(notes)
Storage.shared().allNotesProject = fakeNotesProject
}
if UserDefaultsManagement.sidebarVisibilityInbox {
let project = Storage.shared().getDefault()
let notes = SidebarItem(name: NSLocalizedString("Inbox", comment: ""), project: project, type: .Inbox)
system.append(notes)
}
if UserDefaultsManagement.sidebarVisibilityTodo {
let todoUrl = defaultURL.appendingPathComponent("Fake Virtual Todo Dir")
let todoLabel = NSLocalizedString("Todo", comment: "")
let fakeTodoProject =
Project(
storage: Storage.shared(),
url: todoUrl,
label: todoLabel,
isVirtual: true
)
let todo =
SidebarItem(name: NSLocalizedString("Todo", comment: ""), project: fakeTodoProject, type: .Todo)
system.append(todo)
Storage.shared().todoProject = fakeTodoProject
}
if UserDefaultsManagement.sidebarVisibilityUntagged {
let todoUrl = defaultURL.appendingPathComponent("Fake Virtual Utagged Dir")
let untaggedLabel = NSLocalizedString("Untagged", comment: "")
let fakeUntaggedProject =
Project(
storage: Storage.shared(),
url: todoUrl,
label: untaggedLabel,
isVirtual: true
)
let todo = SidebarItem(name: NSLocalizedString("Untagged", comment: ""), project: fakeUntaggedProject, type: .Untagged)
system.append(todo)
Storage.shared().untaggedProject = fakeUntaggedProject
}
if UserDefaultsManagement.sidebarVisibilityTrash {
let trashProject = Storage.shared().getDefaultTrash()
let trash = SidebarItem(name: NSLocalizedString("Trash", comment: ""), project: trashProject, type: .Trash)
system.append(trash)
}
if system.count > 0 {
list = system
}
list.append(SidebarItem(name: "projects", type: .Separator))
let projects = storage.getSidebarProjects()
if projects.count > 0 {
for project in projects {
list.append(project)
}
}
list.append(SidebarItem(name: "tags", type: .Separator))
}
public func getList() -> [Any] {
return list
}
private func getDefaultLabelName(project: Project) -> String {
var name = project.label
let iCloudPath = "/Users/\(NSUserName())/Library/Mobile Documents"
if project.url.path.starts(with: iCloudPath) {
name = NSLocalizedString("iCloud Drive", comment: "")
}
let documentsPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.path
if let path = documentsPath, project.url.path.starts(with: path) {
name = NSLocalizedString("Documents", comment: "")
}
return name
}
}
================================================
FILE: FSNotes/Helpers/UserDataService.swift
================================================
//
// UserDataService.swift
// FSNotes
//
// Created by Oleksandr Glushchenko on 1/30/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import Foundation
#if os(iOS)
import UIKit
#endif
public class UserDataService {
public static let instance = UserDataService()
fileprivate var _searchTrigger = false
fileprivate var _lastRenamed: URL?
fileprivate var _isNotesTableEscape = false
fileprivate var _isDark = false
fileprivate var _lastType: Int?
fileprivate var _lastProject: URL?
fileprivate var _lastName: String?
fileprivate var _importProgress = false
public var searchTrigger: Bool {
get {
return _searchTrigger
}
set {
_searchTrigger = newValue
}
}
public var focusOnImport: URL? {
get {
return _lastRenamed
}
set {
_lastRenamed = newValue
}
}
public var isNotesTableEscape: Bool {
get {
return _isNotesTableEscape
}
set {
_isNotesTableEscape = newValue
}
}
public var isDark: Bool {
get {
#if os(iOS)
return UITraitCollection.current.userInterfaceStyle == .dark
#else
return _isDark
#endif
}
set {
_isDark = newValue
}
}
public var lastType: Int? {
get {
return _lastType
}
set {
_lastType = newValue
}
}
public var lastName: String? {
get {
return _lastName
}
set {
_lastName = newValue
}
}
public var lastProject: URL? {
get {
return _lastProject
}
set {
_lastProject = newValue
}
}
public func resetLastSidebar() {
_lastProject = nil
_lastType = nil
_lastName = nil
}
public var skipSidebarSelection: Bool {
get {
return _importProgress
}
set {
_importProgress = newValue
}
}
}
================================================
FILE: FSNotes/Images.xcassets/AppIcon.appiconset/Contents.json
================================================
{
"images" : [
{
"filename" : "icon_16x16.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "16x16"
},
{
"filename" : "icon_16x16@2x.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "16x16"
},
{
"filename" : "icon_32x32.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "32x32"
},
{
"filename" : "icon_32x32@2x.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "32x32"
},
{
"filename" : "icon_128x128.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "128x128"
},
{
"filename" : "icon_128x128@2x.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "128x128"
},
{
"filename" : "icon_256x256.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "256x256"
},
{
"filename" : "icon_256x256@2x.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "256x256"
},
{
"filename" : "icon_512x512.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "512x512"
},
{
"filename" : "icon_512x512@2x.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "512x512"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes/Images.xcassets/Contents.json
================================================
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes/Images.xcassets/Icons/AppIconClassic.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "icon_alt.png",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes/Images.xcassets/Icons/AppIconModern.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "icon.png",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes/Images.xcassets/Icons/Contents.json
================================================
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes/Images.xcassets/checkbox_empty.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "checkbox_empty.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "checkbox_empty_white.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "checkbox_empty@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "checkbox_empty_white@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "checkbox_empty@3x.png",
"idiom" : "universal",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "checkbox_empty_white@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes/Images.xcassets/checkbox_flipped.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "checkbox_flipped.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "checkbox_flipped_white.png",
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "checkbox_flipped@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "checkbox_flipped_white@2x.png",
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "checkbox_flipped@3x.png",
"scale" : "3x"
},
{
"idiom" : "universal",
"scale" : "3x",
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
]
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: FSNotes/Images.xcassets/checkbox_new.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "checkbox.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "checkbox_white.png",
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "checkbox@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "checkbox_white@2x.png",
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "checkbox@3x.png",
"scale" : "3x"
},
{
"idiom" : "universal",
"filename" : "checkbox_white@3x.png",
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: FSNotes/Images.xcassets/code.colorset/Contents.json
================================================
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0.940",
"alpha" : "1.000",
"blue" : "0.950",
"green" : "0.950"
}
}
},
{
"idiom" : "universal",
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0.270",
"alpha" : "1.000",
"blue" : "0.270",
"green" : "0.270"
}
}
}
]
}
================================================
FILE: FSNotes/Images.xcassets/colors_background/Contents.json
================================================
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes/Images.xcassets/colors_background/background_tag.colorset/Contents.json
================================================
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xEA",
"green" : "0xA8",
"red" : "0x78"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x63",
"green" : "0x84",
"red" : "0x53"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes/Images.xcassets/colors_background/background_win.colorset/Contents.json
================================================
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xFF",
"green" : "0xFF",
"red" : "0xFF"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x23",
"green" : "0x20",
"red" : "0x20"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes/Images.xcassets/copy.png.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "copy-2.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "copy_white-1.png",
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "copy-1.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "copy_white.png",
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "copy.png",
"scale" : "3x"
},
{
"idiom" : "universal",
"scale" : "3x",
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
]
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: FSNotes/Images.xcassets/divider.colorset/Contents.json
================================================
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0xE9",
"alpha" : "1.000",
"blue" : "0xE9",
"green" : "0xE9"
}
}
},
{
"idiom" : "universal",
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0x00",
"alpha" : "1.000",
"blue" : "0x00",
"green" : "0x00"
}
}
}
]
}
================================================
FILE: FSNotes/Images.xcassets/dockIcon2.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "image@1x.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "image@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "image@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes/Images.xcassets/dockIcon4.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "icon-64.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "icon-128.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "icon-256.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes/Images.xcassets/friend.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "friend.png",
"idiom" : "mac",
"scale" : "1x"
},
{
"filename" : "friend 1.png",
"idiom" : "mac",
"scale" : "2x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes/Images.xcassets/highlight.colorset/Contents.json
================================================
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "1.000",
"alpha" : "1.000",
"blue" : "0.700",
"green" : "0.900"
}
}
},
{
"idiom" : "universal",
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0.200",
"alpha" : "1.000",
"blue" : "0.070",
"green" : "0.550"
}
}
}
]
}
================================================
FILE: FSNotes/Images.xcassets/link.colorset/Contents.json
================================================
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0.240",
"alpha" : "1.000",
"blue" : "0.890",
"green" : "0.510"
}
}
},
{
"idiom" : "universal",
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0.490",
"alpha" : "1.000",
"blue" : "0.630",
"green" : "0.920"
}
}
}
]
}
================================================
FILE: FSNotes/Images.xcassets/locked.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "locked.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "locked-1.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "locked-2.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: FSNotes/Images.xcassets/mainBackground.colorset/Contents.json
================================================
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0xFF",
"alpha" : "1.000",
"blue" : "0xFF",
"green" : "0xFF"
}
}
},
{
"idiom" : "universal",
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0x2A",
"alpha" : "1.000",
"blue" : "0x2E",
"green" : "0x2B"
}
}
}
]
}
================================================
FILE: FSNotes/Images.xcassets/mainText.colorset/Contents.json
================================================
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0.000",
"alpha" : "1.000",
"blue" : "0.000",
"green" : "0.000"
}
}
},
{
"idiom" : "universal",
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "1.000",
"alpha" : "1.000",
"blue" : "1.000",
"green" : "1.000"
}
}
}
]
}
================================================
FILE: FSNotes/Images.xcassets/menuBar.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "icon-simple-bw-b-9-512x512@2x-2.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "icon-simple-bw-w-9-512x512@2x.png",
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "icon-simple-bw-b-9-512x512@2x-1.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "icon-simple-bw-w-9-512x512@2x-1.png",
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "icon-simple-bw-b-9-512x512@2x.png",
"scale" : "3x"
},
{
"idiom" : "universal",
"filename" : "icon-simple-bw-w-9-512x512@2x-2.png",
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: FSNotes/Images.xcassets/new_note_button.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "new_note-76.png",
"idiom" : "mac",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "new_note-77.png",
"idiom" : "mac",
"scale" : "1x"
},
{
"filename" : "new_note-76@2x.png",
"idiom" : "mac",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "new_note-76@2x-1.png",
"idiom" : "mac",
"scale" : "2x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes/Images.xcassets/pin.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "pin.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "pin_white.png",
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "pin-1.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "pin_white-1.png",
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "pin-2.png",
"scale" : "3x"
},
{
"idiom" : "universal",
"scale" : "3x",
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
]
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: FSNotes/Images.xcassets/prefsAdvanced.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "image@1x.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "image@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "image@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes/Images.xcassets/prefsEditor.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "editor.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "editor@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "editor@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes/Images.xcassets/prefsGeneral.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "image@1x.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "image@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "image@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes/Images.xcassets/prefsGit.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "git.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "git@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "git@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes/Images.xcassets/prefsLayout.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "layout.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "layout@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "layout@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes/Images.xcassets/prefsWeb.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "prefsWeb-64.png",
"idiom" : "mac",
"scale" : "1x"
},
{
"filename" : "prefsWeb-128.png",
"idiom" : "mac",
"scale" : "2x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes/Images.xcassets/privacy.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "privacy.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "privacy@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "privacy@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes/Images.xcassets/quoteColor.colorset/Contents.json
================================================
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0x81",
"alpha" : "1.000",
"blue" : "0x81",
"green" : "0x81"
}
}
},
{
"idiom" : "universal",
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0x80",
"alpha" : "1.000",
"blue" : "0x80",
"green" : "0x80"
}
}
}
]
}
================================================
FILE: FSNotes/Images.xcassets/reverseBackground.colorset/Contents.json
================================================
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0x2A",
"alpha" : "1.000",
"blue" : "0x2E",
"green" : "0x2B"
}
}
},
{
"idiom" : "universal",
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0xFF",
"alpha" : "1.000",
"blue" : "0xFF",
"green" : "0xFF"
}
}
}
]
}
================================================
FILE: FSNotes/Images.xcassets/sidebar_archive.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "Archive-76.png",
"idiom" : "mac",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "Archive-77.png",
"idiom" : "mac",
"scale" : "1x"
},
{
"filename" : "Archive-76@2x-1.png",
"idiom" : "mac",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "Archive-76@2x.png",
"idiom" : "mac",
"scale" : "2x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"localizable" : true
}
}
================================================
FILE: FSNotes/Images.xcassets/sidebar_external.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "185097_database_icon-32.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "185097_database_icon-64.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "185097_database_icon-128.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes/Images.xcassets/sidebar_icloud_drive.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "1820466_brand_icloud_logo_network_social_icon-32.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "1820466_brand_icloud_logo_network_social_icon-64.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "1820466_brand_icloud_logo_network_social_icon-128.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes/Images.xcassets/sidebar_inbox.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "1172241_inbox_letter_mail_mailbox_icon-76.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "1172241_inbox_letter_mail_mailbox_icon-77.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "1172241_inbox_letter_mail_mailbox_icon-76@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "1172241_inbox_letter_mail_mailbox_icon-76@2x-1.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "1172241_inbox_letter_mail_mailbox_icon-83.5@2x.png",
"idiom" : "universal",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "1172241_inbox_letter_mail_mailbox_icon-83.5@2x-1.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes/Images.xcassets/sidebar_notes.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "Notes-77.png",
"idiom" : "mac",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "Notes-76.png",
"idiom" : "mac",
"scale" : "1x"
},
{
"filename" : "Notes-76@2x-1.png",
"idiom" : "mac",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "Notes-76@2x.png",
"idiom" : "mac",
"scale" : "2x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes/Images.xcassets/sidebar_project.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "folder-76.png",
"idiom" : "mac",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "folder-77.png",
"idiom" : "mac",
"scale" : "1x"
},
{
"filename" : "folder-76@2x.png",
"idiom" : "mac",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "folder-76@2x-1.png",
"idiom" : "mac",
"scale" : "2x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes/Images.xcassets/sidebar_project_encrypted_locked.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "Folder3lock4 3.png",
"idiom" : "mac",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "Folder3lock4 3-2.png",
"idiom" : "mac",
"scale" : "1x"
},
{
"filename" : "Folder3lock4 3-1.png",
"idiom" : "mac",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "Folder3lock4 3-3.png",
"idiom" : "mac",
"scale" : "2x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes/Images.xcassets/sidebar_project_encrypted_unlocked.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "Folder_unlock_1.png",
"idiom" : "mac",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "Folder_unlock_1-2.png",
"idiom" : "mac",
"scale" : "1x"
},
{
"filename" : "Folder_unlock_1-1.png",
"idiom" : "mac",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "Folder_unlock_1-3.png",
"idiom" : "mac",
"scale" : "2x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes/Images.xcassets/sidebar_tag.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "tag-76.png",
"idiom" : "mac",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "tag-77.png",
"idiom" : "mac",
"scale" : "1x"
},
{
"filename" : "tag-76@2x.png",
"idiom" : "mac",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "tag-76@2x-1.png",
"idiom" : "mac",
"scale" : "2x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes/Images.xcassets/sidebar_todo.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "t2-77.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "t2-76.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "t2-76@2x-1.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "t2-76@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "t2-83.5@2x-1.png",
"idiom" : "universal",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "t2-83.5@2x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes/Images.xcassets/sidebar_trash.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "Trash-77.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "Trash-76.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Trash-76@2x-1.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "Trash-76@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Trash-83.5@2x-1.png",
"idiom" : "universal",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "Trash-83.5@2x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes/Images.xcassets/sidebar_untagged.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "Untagged-76.png",
"idiom" : "mac",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "Untagged-77.png",
"idiom" : "mac",
"scale" : "1x"
},
{
"filename" : "Untagged-76@2x.png",
"idiom" : "mac",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "Untagged-76@2x-1.png",
"idiom" : "mac",
"scale" : "2x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes/Images.xcassets/web.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "web.png",
"idiom" : "mac",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "web 2.png",
"idiom" : "mac",
"scale" : "1x"
},
{
"filename" : "web 1.png",
"idiom" : "mac",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "web 3.png",
"idiom" : "mac",
"scale" : "2x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes/Info.plist
================================================
ATSApplicationFontsPath
.
CFBundleDevelopmentRegion
$(DEVELOPMENT_LANGUAGE)
CFBundleDisplayName
FSNotes
CFBundleDocumentTypes
CFBundleTypeExtensions
etp
CFBundleTypeIconFile
EncryptedTextPack
CFBundleTypeMIMETypes
CFBundleTypeName
Encrypted Text Pack
CFBundleTypeRole
Editor
LSHandlerRank
Owner
LSItemContentTypes
es.fsnot.etp.package
LSTypeIsPackage
0
NSDocumentClass
CFBundleTypeExtensions
textbundle
CFBundleTypeIconFile
TextBundle
CFBundleTypeName
TextBundle
CFBundleTypeRole
Editor
LSHandlerRank
Default
LSItemContentTypes
org.textbundle.package
LSTypeIsPackage
1
NSDocumentClass
CFBundleTypeExtensions
md
markdown
CFBundleTypeIconFile
Markdown
CFBundleTypeName
Markdown
CFBundleTypeRole
Editor
LSHandlerRank
Default
LSItemContentTypes
net.daringfireball.markdown
CFBundleTypeExtensions
rtf
CFBundleTypeIconFile
RTF
CFBundleTypeName
Rich Text
CFBundleTypeRole
Editor
LSHandlerRank
Alternate
LSItemContentTypes
public.rtf
CFBundleTypeExtensions
txt
plain-text
CFBundleTypeIconFile
Text
CFBundleTypeName
Text
CFBundleTypeRole
Editor
LSHandlerRank
Alternate
LSItemContentTypes
public.plain-text
CFBundleExecutable
$(EXECUTABLE_NAME)
CFBundleIdentifier
$(PRODUCT_BUNDLE_IDENTIFIER)
CFBundleInfoDictionaryVersion
6.0
CFBundleName
FSNotes
CFBundlePackageType
APPL
CFBundleShortVersionString
$(MARKETING_VERSION)
CFBundleURLTypes
CFBundleTypeRole
Viewer
CFBundleURLIconFile
icon
CFBundleURLName
co.fluder.fsnotes
CFBundleURLSchemes
fsnotes
CFBundleTypeRole
Viewer
CFBundleURLIconFile
icon
CFBundleURLName
co.fluder.fsnotes
CFBundleURLSchemes
nv
CFBundleTypeRole
Viewer
CFBundleURLIconFile
icon
CFBundleURLName
co.fluder.fsnotes
CFBundleURLSchemes
nvalt
CFBundleVersion
$(CURRENT_PROJECT_VERSION)
LSApplicationCategoryType
public.app-category.productivity
LSMinimumSystemVersion
$(MACOSX_DEPLOYMENT_TARGET)
LSUIElement
NSAppTransportSecurity
NSAllowsArbitraryLoads
NSHumanReadableCopyright
Copyright © 2017-2022 Oleksandr Hlushchenko. All rights reserved.
NSMainStoryboardFile
Main
NSPrincipalClass
NSApplication
NSUbiquitousContainers
iCloud.co.fluder.fsnotes
NSUbiquitousContainerIsDocumentScopePublic
NSUbiquitousContainerName
FSNotes
NSUbiquitousContainerSupportedFolderLevels
One
NSUserActivityTypes
es.fsnot.handoff-open-note
UTExportedTypeDeclarations
UTTypeConformsTo
public.data
UTTypeDescription
Encrypted Text Pack
UTTypeIconFile
EncryptedTextPack
UTTypeIdentifier
es.fsnot.etp.package
UTTypeReferenceURL
https://fsnot.es
UTTypeTagSpecification
public.filename-extension
etp
public.mime-type
UTTypeConformsTo
com.apple.package
UTTypeDescription
TextBundle
UTTypeIconFile
TextBundle
UTTypeIdentifier
org.textbundle.package
UTTypeReferenceURL
http://www.textbundle.org
UTTypeTagSpecification
public.filename-extension
textbundle
UTTypeConformsTo
public.plain-text
UTTypeDescription
Markdown
UTTypeIconFile
Markdown
UTTypeIdentifier
net.daringfireball.markdown
UTTypeTagSpecification
public.filename-extension
md
markdown
public.mime-type
text/markdown
UTTypeConformsTo
public.text
UTTypeDescription
Plain Text
UTTypeIconFile
Text
UTTypeIdentifier
public.plain-text
UTTypeTagSpecification
public.filename-extension
txt
public.mime-type
text/plain
UTTypeConformsTo
public.text
UTTypeDescription
Rich Text
UTTypeIconFile
RTF
UTTypeIdentifier
public.rtf
UTTypeTagSpecification
public.filename-extension
rtf
public.mime-type
text/rtf
================================================
FILE: FSNotes/LayoutManager.swift
================================================
//
// CustomLayoutManager.swift
// FSNotes
//
// Created by Oleksandr Hlushchenko on 24.08.2025.
// Copyright © 2025 Oleksandr Hlushchenko. All rights reserved.
//
import Cocoa
fileprivate extension NSRange {
/// Clamp range to fit inside given maxRange
func clamped(to maxRange: NSRange) -> NSRange {
if maxRange.length == 0 { return NSRange(location: maxRange.location, length: 0) }
if self.location >= NSMaxRange(maxRange) { return NSRange(location: NSMaxRange(maxRange), length: 0) }
let start = max(self.location, maxRange.location)
let end = min(NSMaxRange(self), NSMaxRange(maxRange))
if end <= start { return NSRange(location: start, length: 0) }
return NSRange(location: start, length: end - start)
}
}
class LayoutManager: NSLayoutManager, NSLayoutManagerDelegate {
weak var processor: TextStorageProcessor?
override init() {
super.init()
self.allowsNonContiguousLayout = true
}
required init?(coder: NSCoder) {
super.init(coder: coder)
self.allowsNonContiguousLayout = true
}
public var lineHeightMultiple: CGFloat = CGFloat(UserDefaultsManagement.lineHeightMultiple)
private var defaultFont: NSFont {
return self.firstTextView?.font ?? NSFont.systemFont(ofSize: NSFont.systemFontSize)
}
private func font(for glyphRange: NSRange) -> NSFont {
guard let textStorage = self.textStorage else {
return defaultFont
}
let characterRange = self.characterRange(forGlyphRange: glyphRange, actualGlyphRange: nil)
let storageRange = NSRange(location: 0, length: textStorage.length)
let safeCharRange = characterRange.clamped(to: storageRange)
guard safeCharRange.length > 0 else {
return defaultFont
}
let attributes = textStorage.attributes(at: safeCharRange.location, effectiveRange: nil)
return attributes[.font] as? NSFont ?? defaultFont
}
private func hasAttachment(in glyphRange: NSRange) -> (hasAttachment: Bool, maxAttachmentHeight: CGFloat) {
guard let textStorage = self.textStorage else {
return (false, 0)
}
let characterRange = self.characterRange(forGlyphRange: glyphRange, actualGlyphRange: nil)
let storageRange = NSRange(location: 0, length: textStorage.length)
let safeCharRange = characterRange.clamped(to: storageRange)
if safeCharRange.length == 0 {
return (false, 0)
}
var maxHeight: CGFloat = 0
var hasAttachment = false
textStorage.enumerateAttribute(.attachment, in: safeCharRange, options: []) { value, _, _ in
if let attachment = value as? NSTextAttachment {
hasAttachment = true
let attachmentBounds = attachment.bounds
maxHeight = max(maxHeight, attachmentBounds.height)
}
}
return (hasAttachment, maxHeight)
}
public func lineHeight(for font: NSFont) -> CGFloat {
let fontLineHeight = self.defaultLineHeight(for: font)
let lineHeight = fontLineHeight * lineHeightMultiple
return lineHeight
}
private func isInCodeBlock(characterIndex: Int) -> Bool {
guard let textStorage = self.textStorage else {
return false
}
let ns = textStorage.string as NSString
let storageFullRange = NSRange(location: 0, length: ns.length)
if characterIndex < 0 || characterIndex >= NSMaxRange(storageFullRange) {
return false
}
guard let codeBlocks = processor?.editor?.note?.codeBlockRangesCache else { return false }
return codeBlocks.contains { NSLocationInRange(characterIndex, $0) }
}
// MARK: - Drawing
override func drawBackground(forGlyphRange glyphsToShow: NSRange, at origin: CGPoint) {
drawCodeBlockBackground(forGlyphRange: glyphsToShow, at: origin)
super.drawBackground(forGlyphRange: glyphsToShow, at: origin)
}
override func fillBackgroundRectArray(_ rectArray: UnsafePointer, count rectCount: Int, forCharacterRange charRange: NSRange, color: NSColor) {
let storageLength = self.textStorage?.length ?? 0
let storageFullRange = NSRange(location: 0, length: storageLength)
let safeCharRange = charRange.clamped(to: storageFullRange)
if color == NSColor.selectedTextBackgroundColor ||
color == NSColor.unemphasizedSelectedTextBackgroundColor ||
!isInCodeBlock(characterIndex: safeCharRange.location) {
super.fillBackgroundRectArray(rectArray, count: rectCount, forCharacterRange: charRange, color: color)
}
}
private func drawCodeBlockBackground(forGlyphRange glyphsToShow: NSRange, at origin: CGPoint) {
guard let textStorage = self.textStorage,
let context = NSGraphicsContext.current?.cgContext else {
return
}
let storageFullRange = NSRange(location: 0, length: textStorage.length)
guard let allCodeBlocks = processor?.editor?.note?.codeBlockRangesCache else { return }
guard let textContainer = self.textContainers.first else { return }
let visibleCharRange = self.characterRange(forGlyphRange: glyphsToShow, actualGlyphRange: nil)
let relevantCodeBlocks = allCodeBlocks.filter { codeBlock in
NSIntersectionRange(codeBlock, visibleCharRange).length > 0
}
guard !relevantCodeBlocks.isEmpty else { return }
textContainer.lineFragmentPadding = 10
context.saveGState()
let backgroundColor = NotesTextProcessor.getHighlighter().options.style.backgroundColor.cgColor
let borderColor = NSColor.lightGray.cgColor
for codeBlockRange in relevantCodeBlocks { // ← теперь только релевантные блоки!
let safeCharRange = codeBlockRange.clamped(to: storageFullRange)
if safeCharRange.length == 0 { continue }
let glyphRange = self.glyphRange(forCharacterRange: safeCharRange, actualCharacterRange: nil)
if glyphRange.length == 0 { continue }
let boundingRect = self.boundingRect(forGlyphRange: glyphRange, in: textContainer)
if boundingRect.isEmpty { continue }
// Padding left/right
let horizontalPadding: CGFloat = 5.0
let paddedRect = boundingRect
.insetBy(dx: -horizontalPadding, dy: 0)
.offsetBy(dx: origin.x, dy: origin.y)
// Round borders
let radius: CGFloat = 5.0
let path = CGPath(roundedRect: paddedRect, cornerWidth: radius, cornerHeight: radius, transform: nil)
context.setFillColor(backgroundColor)
context.addPath(path)
context.fillPath()
// Border 1px
context.addPath(path)
context.setStrokeColor(borderColor)
context.setLineWidth(1.0)
context.strokePath()
}
context.restoreGState()
}
public func layoutManager(
_ layoutManager: NSLayoutManager,
shouldSetLineFragmentRect lineFragmentRect: UnsafeMutablePointer,
lineFragmentUsedRect: UnsafeMutablePointer,
baselineOffset: UnsafeMutablePointer,
in textContainer: NSTextContainer,
forGlyphRange glyphRange: NSRange) -> Bool {
// Get the font for the current range of glyphs
let currentFont = font(for: glyphRange)
let fontLineHeight = layoutManager.defaultLineHeight(for: currentFont)
let standardLineHeight = fontLineHeight * lineHeightMultiple
let attachmentInfo = hasAttachment(in: glyphRange)
var finalLineHeight: CGFloat
var baselineNudge: CGFloat
if attachmentInfo.hasAttachment && attachmentInfo.maxAttachmentHeight > 0 {
if attachmentInfo.maxAttachmentHeight > standardLineHeight {
finalLineHeight = attachmentInfo.maxAttachmentHeight
baselineNudge = 0
} else {
finalLineHeight = standardLineHeight
let extraSpace = finalLineHeight - fontLineHeight
baselineNudge = extraSpace * 0.5
}
} else {
finalLineHeight = standardLineHeight
let extraSpace = finalLineHeight - fontLineHeight
baselineNudge = extraSpace * 0.5
}
var rect = lineFragmentRect.pointee
rect.size.height = ceil(finalLineHeight)
var usedRect = lineFragmentUsedRect.pointee
usedRect.size.height = max(rect.size.height, ceil(usedRect.size.height))
lineFragmentRect.pointee = rect
lineFragmentUsedRect.pointee = usedRect
baselineOffset.pointee = baselineOffset.pointee + baselineNudge
return true
}
func refreshLayoutSoftly() {
invalidateLayout(forCharacterRange: NSRange(location: 0, length: textStorage?.length ?? 0),
actualCharacterRange: nil)
textContainers.forEach { container in
container.textView?.needsDisplay = true
}
}
override func setExtraLineFragmentRect(
_ fragmentRect: NSRect,
usedRect: NSRect,
textContainer container: NSTextContainer) {
var fontToUse: NSFont
if let textStorage = self.textStorage, textStorage.length > 0 {
let lastIndex = textStorage.length - 1
let attributes = textStorage.attributes(at: lastIndex, effectiveRange: nil)
let nsString = textStorage.string as NSString
let lastCharIsNewline = nsString.character(at: lastIndex) == 0x0A // '\n'
if !lastCharIsNewline, let font = attributes[.font] as? NSFont {
fontToUse = font
} else {
fontToUse = UserDefaultsManagement.noteFont
}
} else {
fontToUse = UserDefaultsManagement.noteFont
}
let lineHeight = self.lineHeight(for: fontToUse)
var fragmentRect = fragmentRect
fragmentRect.size.height = ceil(lineHeight)
var usedRect = usedRect
usedRect.size.height = ceil(lineHeight)
super.setExtraLineFragmentRect(fragmentRect,
usedRect: usedRect,
textContainer: container)
}
}
================================================
FILE: FSNotes/Localizable.xcstrings
================================================
{
"sourceLanguage" : "en",
"strings" : {
"Add" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "يضيف"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Přidat"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hinzufügen"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Añadir"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ajouter"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הוסף"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "जोड़ें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aggiungi"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "追加"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "추가"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Toevoegen"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Adicionar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Adicionar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Добавить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ekle"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Додати"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "添加"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "新增"
}
}
}
},
"Add External Folder..." : {
"comment" : "Menu Library",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "ارفاق تخزين..."
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Přidat externí složku"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Speicher anschließen..."
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Adjuntar almacenamiento..."
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Attacher un stockage..."
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הוסף תיקיה חיצונית..."
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "बाह्य फ़ोल्डर जोड़ें..."
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Collega archivio..."
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "外部フォルダを追加…"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "저장소 추가..."
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Koppelen opslag..."
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Adicionar pasta externa..."
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Adicionar armazenamento..."
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Подключить хранилище..."
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Harici Klasör Ekle..."
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Підключити сховище..."
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "附件存储..."
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "附件存檔"
}
}
}
},
"Are you really want to remove %d tag(s)? This action can not be undone." : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "هل تريد حقًا إزالة٪ d علامة (علامات)؟ لا يمكن التراجع عن هذا الإجراء."
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Opravdu chcete odstranit tyto značky (%d)? Tuto akci nelze odvolat."
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Möchten Sie wirklich %d Tag(s) entfernen? Diese Aktion kann nicht rückgängig gemacht werden."
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "¿Seguro que quieres borrar %d etiqueta/s? Esta operación no se puede deshacer."
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Êtes-vous sûr de vouloir supprimer %d étiquette(s) ? Cette action est irréversible."
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "האם ברצונך להסיר %d תג(ים)? לא ניתן לבטל פעולה זו."
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "क्या आप वाकई %d टैग हटाना चाहते हैं? यह क्रिया पूर्ववत नहीं की जा सकती।"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vuoi veramente rimuovere %d tag(s)? Questa azione non può essere annullata."
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "本当にこれら%d個のタグを削除しますか?一度削除したら元に戻すことはできません"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Are you really want to remove %d tag(s)? This action can not be undone."
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Are you really want to remove %d tag(s)? This action can not be undone."
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tem certeza que deseja remover %d tag(s)? Essa ação não pode ser desfeita."
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tem a certeza que pretende remover %d etiqueta(s)? Esta acção é irreversível."
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вы действительно хотите удалить %d тег(ов)? Это действие не может быть отменено."
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Gerçekten %d etiketi kaldırmak istiyor musunuz? Bu işlem geri alınamaz."
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ви дійсно хочете видалити %d тег(и)? Ця дія не може бути скасована."
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "您真的要删除 %d 个标签吗?此操作无法撤消。"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "確定要刪除 %d 個標籤嗎?此動作無法復原"
}
}
}
},
"Are you sure you want to irretrievably delete %d note(s)?" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "هل انت متأكد من حذف الملفات %d بشكل نهائي ؟"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Určitě chcete nenávratně smazat tyto poznámky (%d)?"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sind Sie sicher, dass Sie %d Notiz(en) unwiderruflich löschen möchten?"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "¿Seguro que quieres borrar definitivamente %d notas?"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Êtes-vous sûr de vouloir supprimer définitivement %d note(s) ?"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "האם ברצונך למחוק %d פתק(ים) באופן בלתי הפיך?"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "क्या आप वाकई %d नोट को पूरी तरह से हटाना चाहते हैं?"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sei sicuro di voler eliminare in modo irreversibile la/e nota/e %d ?"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "これら%d件のノートを本当に削除してもいいですか?(もとに戻せません)"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "%d개의 노트를 영구적으로 지우겠습니까?"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Weet je zeker dat je %d notitie(s) definitief wilt wissen?"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tem certeza que deseja deletar as notas %d irreversivelmente?"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tem a certeza que pretende eliminar %d nota(s) de forma irreversível?"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вы уверены что хотите выполнить необратимое удаление %d заметки(ок)?"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "%d notu geri alınamaz şekilde silmek istediğinizden emin misiniz?"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вы впевнені що хочете назавжди видалити %d нотатку(ок)? "
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "确定要永久删除%d个笔记?此操作无法恢复!"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "確定要永久刪除 %d 個筆記嗎?此操作無法復原!"
}
}
}
},
"Are you sure you want to remove project \"%@\" and all files inside?" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "هل انت متأكد من حذف المشروع \"%@\" وكل المفات التي بداخله"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Opravdu chcete odebrat projekt „%@“ včetně všech souborů uvnitř?"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sind Sie sicher, dass Sie Projekt \"%@\" löschen möchten?"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "¿Seguro que quieres borrar el proyecto \"%@\" con todo su contenido?"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Êtes-vous sûr de vouloir supprimer le projet \"%@\" et tous ses fichiers ?"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "האם ברצונך להסיר פרוייקט \"%@\" ואת כל הקבצים שבתוכו?"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "क्या आप वाकई प्रोजेक्ट \"%@\" और उसके अंदर की सभी फाइलें हटाना चाहते हैं?"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sei sicuro di voler eliminare il progetto \"%@\" e tutti i file al suo interno?"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "プロジェクト \"%@\" と中に入っているすべてのノートを本当に削除してもいいですか?"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "프로젝트 \"%@\"를 영구적으로 지우겠습니까?"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Weet je zeker dat je project \"%@\" en alle bestanden daarin wilt verwijderen?"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tem certeza de que pretende remover o projeto \"%@\" e todos os arquivos contidos nele?"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tem a certeza que pretende eliminar o projeto \"%@\" e todos os seus ficheiros?"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вы уверены, что хотите удалить проект \"%@\" и все файлы в нем?"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "\"@\" projesini ve içindeki tüm dosyaları kaldırmak istediğinizden emin misiniz?"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вы впевнені що хочете видалити директорію \"%@\"?"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "您确定要删除项目\"%@\"和它下面的所有文件吗?"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "您確定要刪除項目\"%@\"和它下面的所有檔案嗎?"
}
}
}
},
"Back up storage" : {
"extractionState" : "manual",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تخزين النسخ الاحتياطي"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zálohovat úložiště"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Speicher sichern"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Almacenamiento de respaldo"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sauvegarder le stockage"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "גבה אחסון"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "संग्रहण का बैकअप लें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Salva archivio"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "バックアップストレージ"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "저장소 백업"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Back-up opslag"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Armazenamento de cópia de segurança"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cópia de segurança de armazenamento"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Создать резервную копию"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Depolamayı yedekle"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Зробити резервну копію"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "提交git的存储库中的所有文件"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "將所有檔案提交到 Git 儲存庫"
}
}
}
},
"Cancel" : {
"comment" : "Delete menu",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "الغاء"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zrušit"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Abbrechen"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cancelar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Annuler"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "ביטול"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "रद्द करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Annulla"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "キャンセル"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "취소"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Annuleer"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cancelar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cancelar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Отмена"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "İptal"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Відміна"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "取消"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "取消"
}
}
}
},
"Change creation date" : {
"comment" : "Menu",
"extractionState" : "manual",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تغيير تاريخ الإنشاء"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Změnit datum vytvoření"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Erstellungsdatum ändern"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cambiar la fecha de creación"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Modifier la date de création"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "שנה את תאריך היצירה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "निर्माण तारीख बदलें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Modifica la data di creazione"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "作成日の変更"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "생성 날짜 변경"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aanmaakdatum wijzigen"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Alterar data de criação"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Alterar data de criação"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Изменить дату создания"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Oluşturma tarihini değiştir"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Змінити дату створення"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "更改创建日期"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "變更建立日期"
}
}
}
},
"Change Creation Date" : {
"comment" : "File Menu\nMenu",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تغيير تاريخ الإنشاء"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Změnit datum vytvoření"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Erstellungsdatum ändern"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cambiar fecha de creación"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Modifier la date de création"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "שנה תאריך יצירה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "निर्माण तारीख बदलें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Modifica la data di creazione"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "作成日を変更"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "생성 일 변경"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Wijzig de aanmaakdatum"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Alterar data de criação"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Alterar data de criação"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Изменить дату создания"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Oluşturma Tarihini Değiştir"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Змінити дату створення"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "变更建立日期"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "變更建立日期"
}
}
}
},
"Clear" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clear"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vyprázdnit"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Klar"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Limpiar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Effacer"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "נקה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "साफ करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pulisci"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "クリア"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clear"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clear"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Limpar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Limpar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Очистить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Temizle"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Очистити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "清除"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "清除"
}
}
}
},
"Clipboard successfully saved" : {
"localizations" : {
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Portapapeles guardado correctamente"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Буфер обмена успешно сохранен"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pano başarıyla kaydedildi"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Буфер обміну успішно збережено"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "剪貼簿已成功儲存"
}
}
}
},
"Close" : {
"comment" : "File Menu",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "اغلاق"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zavřít"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Schließen"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cerrar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fermer"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "סגור"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "बंद करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Chiudi"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "閉じる"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "닫기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sluit"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fechar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fechar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Закрыть"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kapat"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Закрити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "关闭"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "關閉"
}
}
}
},
"Commit & Push “%@”" : {
"comment" : "Menu Library",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Commit & Push “%@”"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Commit & Push “%@”"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Commit & Push “%@”"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Commit & Push “%@”"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Commit & Push “%@”"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Commit & Push “%@”"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "Commit & Push “%@”"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Commit & Push “%@”"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Commit & Push “%@”"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Commit & Push “%@”"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Commit & Push “%@”"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Commit & Push “%@”"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Commit & Push “%@”"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Закоммитить “%@”"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Commit & Push “%@”"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Закомітити “%@”"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "Commit & Push “%@”"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "送出並上傳“%@”"
}
}
}
},
"Commit message:" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Commit message:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Popisek commitu:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Commit message:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Commit message:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Message du Commit :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "אשר הודעה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कमिट संदेश:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Commit message:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Commit message:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Commit message:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Commit message:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mensagem de confirmação:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Commit message:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сообщение коммита:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mesajı kaydet:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Коментар до коміту:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "提交消息:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "送出訊息"
}
}
}
},
"Connection established successfully 🤟" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تم الاتصال بنجاح 🤟"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Připojení úspěšně navázáno 🤟"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verbindung erfolgreich hergestellt 🤟"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Connection established successfully 🤟"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Connexion établie avec succès 🤟"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "החיבור נוצר בהצלחה 🤟"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कनेक्शन सफलतापूर्वक स्थापित हो गया 🤟"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Connessione stabilita con successo 🤟"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "接続が確立されました🤟"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "성공적으로 연결되었습니다 🤟"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Connection established successfully 🤟"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Conexão estabelecida com sucesso 🤟"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Conexão estabelecida com sucesso 🤟"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Соединение успешно установлено 🤟"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bağlantı başarıyla kuruldu 🤟"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "З'єднання встановлено успішно 🤟"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "连接建立成功🤟"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "連線已成功建立🤟"
}
}
}
},
"Convert to Plain" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Convert to Plain"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Převést na prostý text"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Konvertieren zu Plain"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Convertir a Plain"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Convertir en texte brut"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "המר לטקסט רגיל"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "सादे में परिवर्तित करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Convertire in PlainText"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "に変換 PlainText"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "로 변환하다 Plain"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Omzetten naar Plain"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Converter para texto simples"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Converter para Plain"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Преобразовать в Plain"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Düze Dönüştür"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перетворити в PlainText"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "转换成纯文本"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "轉換為純文字"
}
}
}
},
"Convert to TextBundle" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Convert to TextBundle"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Převést na TextBundle"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Konvertieren zu TextBundle"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Convertir a TextBundle"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Convertir en TextBundle"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "להמיר ל TextBundle"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "टेक्स्टबंडल में परिवर्तित करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Convertire in TextBundle"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "に変換 TextBundle"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "로 변환하다 TextBundle"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Omzetten naar TextBundle"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Converter para TextBundle"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Converter para TextBundle"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Преобразовать в TextBundle"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "TextBundle'a Dönüştür"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перетворити в TextBundle"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "转换成 TextBundle"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "轉換為TextBundle"
}
}
}
},
"Copy HTML" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "نسخ HTML"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kopírovat HTML"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "HTML kopieren"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copiar HTML"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copier HTML"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "העתק HTML"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "HTML कॉपी करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copia HTML"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "HTMLをコピー"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "HTML 복사하기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kopieer HTML"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copiar HTML"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copiar HTML"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Скопировать HTML"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "HTML'yi Kopyala"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Скопіювати HTML"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "拷贝HTML"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "複製HTML"
}
}
}
},
"Copy Link" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "نسخ الرابط"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zkopírovat odkaz"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Link kopieren"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copiar enlace"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copier le lien"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "העתק קישור"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "लिंक कॉपी करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copia Link"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "リンクをコピー"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "링크 복사하기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kopieer Link"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copiar Link"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copiar Ligação"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Скопировать ссылку"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bağlantıyı Kopyala"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Скопіювати посилання"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "拷贝链接"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "複製連結"
}
}
}
},
"Copy Plain Text" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "نسخ نص اعتيادي"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kopírovat prostý text"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Plain Text kopieren"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copiar texto sin estilo"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copier le texte brut"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "העתק מלל פשוט"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "सादा पाठ कॉपी करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copia Testo Semplice"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "プレインテキストとしてコピー"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "일반 텍스트 복사하기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kopieer Platte Tekst"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copiar Texto Simples"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copiar Texto Simples"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Скопировать чистый текст"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Düz Metni Kopyala"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Скопіювати текст"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "拷贝纯文本"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "複製純文字"
}
}
}
},
"Copy Title" : {
"comment" : "File Menu",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "نسخ العنوان"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kopírovat nadpis"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Title kopieren"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copiar título"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copier le titre"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "העתק כותרת"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "शीर्षक कॉपी करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copia titolo"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "タイトルをコピー"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "제목 복사"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kopieer titel"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copiar título"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copiar título"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Скопировать заголовок"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Başlığı Kopyala"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Скопіювати заголовок"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "拷贝标题"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "複製標題"
}
}
}
},
"Copy URL" : {
"comment" : "File Menu",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "نسخ URL"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kopírovat URL"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "URL kopieren"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copiar enlace"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copier l'URL"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "העתק כתובת"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "यूआरएल कॉपी करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copia URL"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "URLをコピー"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "URL 복사"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kopieer URL"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copiar URL"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copiar endereço URL"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Скопировать ссылку"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "URLyi Kopyala"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Скопіювати посилання"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "拷贝URL"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "複製 URL"
}
}
}
},
"Create Folder" : {
"comment" : "Menu Library",
"localizations" : {
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Crear carpeta"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Создать директорию"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Klasör Oluştur"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Створити директорію"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "建立資料夾"
}
}
}
},
"Create Web Page" : {
"comment" : "File Menu",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "إنشاء صفحة ويب"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vytvořit webovou stránku"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Online teilen"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Crear página web"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Créer une page Web"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "צור דף אינטרנט"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "वेब पेज बनाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Crea pagina web"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ウェブページの作成"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "웹 페이지 만들기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Create Web Page"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Criar página Web"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Criar página da Web"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Создать веб-страницу"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web Sayfası Oluştur"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Створити веб-сторінку"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "创建为网页URL"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "建立網頁"
}
}
}
},
"Creation date:" : {
"comment" : "Menu",
"extractionState" : "manual",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تاريخ الإنشاء:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Datum vytvoření:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Erstellungsdatum:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fecha de creación:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Date de création :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "תאריך יצירה:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "निर्माण तारीख:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Data di creazione:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "作成日:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "제작 일:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Creation date:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Data de criação:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Data de criação:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Дата создания:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Oluşturma tarihi:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Дата створення:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "创建日期:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "建立日期:"
}
}
}
},
"Current password does not match with password in keychain" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "كلمة المرور الحالية لا تتطابق مع كلمة المرور في keychain"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Současné heslo se neshoduje s heslem v klíčence"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Das aktuelle Passwort stimmt nicht mit dem Passwort im Schlüsselbund überein"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "La contraseña actual no coincide con la contraseña en el Llavero"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Le mot de passe actuel ne correspond pas au mot de passe du trousseau"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הסיסמה הנוכחית לא תואמת עם הסיסמה בצרור"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "वर्तमान पासवर्ड कीचेन में दिए गए पासवर्ड से मेल नहीं खाता"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "La password corrente non corrisponde alla password nel portachiavi"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "現在のパスワードはKeychainに保存されたものと一致しません"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "암호가 키체인과 다릅니다"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Het huidige wachtwoord komt niet overeen met het wachtwoord in de sleutelhanger"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "A senha atual não corresponde à senha no keychain"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "A palavra-passe atual não coincide com a palavra-passe armazenada no keychain"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Пароль не соответствует паролю в связке"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Geçerli parola anahtarlık içindeki parolayla uyuşmuyor"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Пароль не співпадає з паролем у зв'язці"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "当前密码与钥匙串中的密码不匹配"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "目前密碼與鑰匙圈中的密碼不符"
}
}
}
},
"Decrypt" : {
"comment" : "File Menu",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "فك تشفير"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dešifrovat"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Entschlüsseln"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Descifrar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Déchiffrer"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "פענח"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "डिक्रिप्ट"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Decifra"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "復号化"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "복호화"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Decrypt"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Descriptografar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Descriptografar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Расшифровать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Şifresini Çöz"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Розшифрувати"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "解密"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "解密"
}
}
}
},
"Decrypt Folder" : {
"comment" : "Menu Library",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "فك تشفير المجلد"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dešifrovat složku"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordner verschlüsseln"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Descifrar carpeta"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Crypter le dossier"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הצפנת תיקיה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "फ़ोल्डर एन्क्रिप्ट करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Crittografa cartella"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "フォルダ復号"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "폴더 암호화"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Map ontsleutelen"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Criptografar pasta"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Descriptografar pasta"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Снять шифрование"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Klasörü Şifresini Çöz"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Зняти шифрування"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "解密文件夹"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "解密資料夾"
}
}
}
},
"Default storage path should not be equal to Git path." : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "يجب ألا يكون مسار التخزين الافتراضي مساويًا لمسار Git."
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cesta pro výchozí úložiště by neměla být totožná s cestou ke Gitu"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Der Standardspeicherpfad sollte nicht gleich dem Git-Pfad sein."
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "La carpeta de almacenamiento por defecto no puede ser un repositorio Git."
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Le chemin de stockage par défaut ne doit pas être égal au chemin Git."
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "נתיב האחסון צריך לא להיות שווה לנתיב Git."
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "डिफ़ॉल्ट संग्रहण पथ गिट पथ के बराबर नहीं होना चाहिए।"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Il percorso di archiviazione predefinito non deve essere uguale al percorso Git."
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "デフォルトストレージパスはGitパスとは異なる必要があります"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "기본 저장 경로는 Git 경로와 같지 않아야 합니다."
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Default storage path should not be equal to Git path."
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "O caminho de armazenamento padão não deve ser igual ao caminho do Git."
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "O caminho de armazenamento por defeito não deve ser igual ao ao path de Git."
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Путь к хранилищу по умолчанию не должен совпадать с путем Git."
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Varsayılan depolama yolu\nGit yoluna eşit olmamalıdır."
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Шлях зберігання за умовчанням не повинен дорівнювати шляху Git."
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "默认存储路径不允许和 Git 路径相同。"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "預設儲存路徑不應與 Git 路徑相同。"
}
}
}
},
"Delete" : {
"comment" : "File Menu",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "حذف"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Smazat"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Löschen"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Eliminar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Supprimer"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "מחק"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "हटाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Elimina"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "削除"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "삭제"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verwijder"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Deletar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Eliminar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Удаление"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sil"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Видалити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "删除"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "刪除"
}
}
}
},
"Delete Folder" : {
"comment" : "Menu Library",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "حذف المجلد"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Smazat složku"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordner löschen"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Eliminar carpeta"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Supprimer le dossier"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "מחק תיקיה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "फ़ोल्डर हटाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Elimina cartella"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "フォルダを削除"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "폴더 삭제"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verwijder map"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Deletar Pasta"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Eliminar pasta"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Удалить директорию"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Klasörü Sil"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Видалити директорію"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "删除文件夹"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "刪除資料夾"
}
}
}
},
"Delete Tag" : {
"comment" : "Menu Library",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "حذف العلامة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Smazat značku"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tag löschen"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Eliminar etiqueta"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Supprimer l’étiquette"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "מחק תג"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "टैग हटाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Elimina tag"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "タグを削除"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "태그 삭제"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verwijder tag"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Deletar Tag"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Eliminar Etiqueta"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Удалить тег"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Etiketi Sil"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Видалити тег"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "删除标签"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "刪除標籤"
}
}
}
},
"Delete Web Page" : {
"comment" : "File Menu",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "حذف صفحة الويب"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Smazat webovou stránku"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Geteilte löschen"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Eliminar página web"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Supprimer la page Web"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "מחק דף אינטרנט"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "वेब पेज हटाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Elimina pagina web"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ウェブページを削除"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "웹 페이지 삭제"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Webpagina verwijderen"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Deletar página Web"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Excluir página da Web"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Удалить веб-страницу"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web Sayfasını Sil"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Видалити веб-сторінку"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "删除网页"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "刪除網頁"
}
}
}
},
"Do you want force checkout?" : {
"extractionState" : "manual",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Do you want force checkout?"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Chcete vynutit checkout?"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Do you want force checkout?"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Do you want force checkout?"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Voulez-vous forcer le checkout ?"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "האם ברצונך לבצע צ'ק-אאוט בכוח?"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "क्या आप जबरन चेकआउट चाहते हैं?"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Do you want force checkout?"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Do you want force checkout?"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Do you want force checkout?"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Do you want force checkout?"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Deseja forçar a saída?"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Do you want force checkout?"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сделать принудительный чекаут?"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ödemeyi zorunlu kılmak ister misiniz?"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Зробити примусовий чекаут?"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "是否要强制检查?"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "您確定要強制切換嗎?"
}
}
}
},
"Do you want to move current notes in the new destination?" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "هل تريد نقل الملاحظات الحالية إلى الوجهة الجديدة؟"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Chcete přesunout současné poznámky do nového cíle?"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Möchten Sie aktuelle Notizen an das neue Ziel verschieben?"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "¿Quieres mover las notas al nuevo destino?"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Voulez-vous déplacer les notes actuelles vers la nouvelle destination ?"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "האם ברצונך להעביר את הפתקים הנוכחים ליעד החדש?"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "क्या आप वर्तमान नोट्स को नए गंतव्य पर ले जाना चाहते हैं?"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vuoi spostare le note correnti nella nuova destinazione?"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "既存のノートを新しい場所に移動しますか?"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "현재 메모를 새 대상으로 이동하시겠습니까?"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Do you want to move current notes in the new destination?"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pretende mover as notas atuais para o novo destino?"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Deseja mover as notas existentes para o novo destino?"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вы хотите переместить текущие заметки в новое место назначения?"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mevcut notları yeni hedefe taşımak ister misiniz?"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ви хочете перемістити поточні нотатки до нового сховища?"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "您想将当前笔记移动到目标处吗?"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "您要將目前的筆記移動到新目的地嗎?"
}
}
}
},
"Documents" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "المستندات"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dokumenty"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Documents"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Documentos"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Documents"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "מסמכים"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "दस्तावेज़"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Documenti"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ドキュメント"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "서류"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Documents"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Documentos"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Documentos"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Документы"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Belgeler"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Документація"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "文档"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "文件"
}
}
}
},
"Done" : {
"localizations" : {
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hecho"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Готово"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tamam"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Готово"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "完成"
}
}
}
},
"Duplicate" : {
"comment" : "File Menu",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "نسخة مكررة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Duplikovat"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Duplizieren"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Duplicar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dupliquer"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "שכפל"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नकल"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Duplica"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "複製"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "복제"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dupliceer"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Duplicar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Duplicar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Создать копию"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kopyala"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Дублювати"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "生成副本"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "製作複本"
}
}
}
},
"Edit Link…" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تحرير الرابط ..."
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Upravit odkaz…"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Edit Link…"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Editar enlace…"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Modifier le lien…"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "ערוך קישור..."
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "लिंक संपादित करें…"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Modifica Link…"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "リンクを修正..."
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "링크 수정…"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bewerk Link..."
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Editar Link..."
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Editar Ligação..."
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Редактировать ссылку..."
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bağlantıyı Düzenle…"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Редагувати посилання..."
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "编辑链接…"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "編輯連結…"
}
}
}
},
"Empty Bin" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "إفراغ سلة المهملات"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vyprázdnit koš"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Papierkorb leeren"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vaciar papelera"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vider la corbeille"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "רוקן סל"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "खाली बिन"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Svuota cestino"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "空のゴミ箱"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "휴지통 비우기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Prullenbak leegmaken"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Esvaziar lixeira"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Esvaziar caixa de lixo"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Очистить корзину"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Çöp Kutusunu Boşalt"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Очистити кошик"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "清空回收站"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "清空垃圾桶"
}
}
}
},
"Empty password" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "كلمة مرور فارغة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Prázdné heslo"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Passwort leer"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Contraseña vacía"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mot de passe vide"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הסיסמה ריקה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "ख़ाली पासवर्ड"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Password vuota"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "パスワードが空です"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "빈 암호"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Leeg wachtwoord"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Senha vazia"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Palavra-passe vazia"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Не введен пароль"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Boş şifre"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Введіть пароль"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "空密码"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "密碼為空"
}
}
}
},
"Enter an encryption password:" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "أدخل كلمة مرور تشفير:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vytvořte šifrovací heslo:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Geben Sie ein Verschlüsselungspasswort ein:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Introduzca una contraseña de cifrado:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Saisir un mot de passe de chiffrement :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הזן סיסמת הצפנה:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "एन्क्रिप्शन पासवर्ड दर्ज करें:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Inserire una password di crittografia:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "暗号化パスワードを入力:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "암호화 비밀번호를 입력하세요:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Voer een coderingswachtwoord in:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Introduzir uma senha de encriptação:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Introduzir uma palavra-passe de encriptação:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Введите пароль шифрования:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bir şifreleme parolası girin:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Введіть пароль шифрування:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "输入加密密码:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "請輸入加密密碼:"
}
}
}
},
"Enter Master Password" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "ادخل كلمة المرور الاساسية"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zadat hlavní heslo"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Geben Sie das Master Passwort ein"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Introduce la contraseña maestra"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Entrez le mot de passe principal"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הכנס סיסמה ראשית"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "मास्टर पासवर्ड दर्ज करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Inserisci la Master Password"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "マスターパスワードを入力する"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "마스터 암호 입력"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Voer Hoofdwachtwoord in"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Introduza a senha mestre"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Introduzir Palavra-passe Mestra"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Введите мастер пароль"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ana Parolayı Girin"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Введіть мастер пароль"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "输入管理员密码"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "請輸入主密碼"
}
}
}
},
"Folder with name '%@' already exist" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "المجلد الذي يحمل الاسم '٪ @' موجود بالفعل"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Složka s názvem „%@“ už existuje"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Folder with name '%@' already exist"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ya existe una carpeta nombrada '%@'"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Le dossier avec le nom '%@' existe déjà"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "תיקיה בשם \"%@\" כבר קיימת."
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "'%@' नाम वाला फ़ोल्डर पहले से मौजूद है"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "La cartella con il nome '%@' già esiste"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "'%@'という名前のフォルダはすでに存在しています"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "이름이 '%@'인 폴더가 이미 있습니다."
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Folder with name '%@' already exist"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "A pasta com o nome '%@' já existe"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Já existe uma pasta com o nome '%@'"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Директория с названием '%@' уже существует"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "'%@' adlı klasör zaten mevcut"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Директорія з назвою '%@' вже існує"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "文件夹名称 '%@' 已存在"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "名為'%@' 的資料夾已存在"
}
}
}
},
"Font" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Font"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Písmo"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Font"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Font"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Police"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "גופן"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "फ़ॉन्ट"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Font"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Font"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Font"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Font"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fonte"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Font"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Шрифт"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Font"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Шрифт"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "字体"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "字體"
}
}
}
},
"Force Delete" : {
"comment" : "File Menu",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "حذف اجباري"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vynutit smazání"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Löschen erzwingen"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Forzar la Eliminación"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Forcer la suppression"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "מחק מיידית"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "बलपूर्वक हटाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Forza Cancellazione"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "強制的に削除"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "강제 삭제"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Forceer verwijderen"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Forçar deletar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Forçar Apagar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Принудительное удаление"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zorla Sil"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Примусово видалити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "强制删除"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "強制刪除"
}
}
}
},
"FSNotes [edit]" : {
"extractionState" : "manual",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes [تعديل]"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes [upravit]"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes [bearbeiten]"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes [edición]"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes [modification]"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes [עריכה]"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes [संपादन]"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes [modifica]"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes [編集]"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes [수정]"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes [bewerk]"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes [editar]"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes [editar]"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes [редактирование]"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes [düzenle]"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes [редагування]"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes [编辑]"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes[編輯]"
}
}
}
},
"FSNotes [preview]" : {
"extractionState" : "manual",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes [المعاينة]"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes [náhled]"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes [Vorschau]"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes [previsualización]"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes [prévisualisation]"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes [תצוגה]"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes [पूर्वावलोकन]"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes [anteprima]"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes [プレビュー]"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes [미리보기]"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes [voorvertoning]"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes [pré-visualização]"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes [pré-visualizar]"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes [предпросмотр]"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes [önizleme]"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes [попередній перегляд]"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes [预览]"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes[預覽]"
}
}
}
},
"git error" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "git error"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "git chyba"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "git error"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "git error"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "erreur git"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "git error"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "गिट त्रुटि"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "git error"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "git error"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "git error"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "git error"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "git error"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "git error"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ошибка git"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "git hatası"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "git error"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "git error"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "git 錯誤"
}
}
}
},
"Git error" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git error"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git chyba"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git error"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git error"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Erreur Git"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git error"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "गिट त्रुटि"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git error"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git error"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git error"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git error"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git error"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git error"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ошибка git"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git hatası"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git error"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git 错误"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "git 錯誤"
}
}
}
},
"Git push error" : {
"extractionState" : "manual",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git push خطأ"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git push chyba"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git push fehler"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git push error"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Erreur Git push"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git push שְׁגִיאָה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "गिट पुश त्रुटि"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git push errore"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git push エラー"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git push 오류"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git push error"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git push error"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git push erro"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ошибка git push"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git Gönderme hatası"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git push помилка"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git 推送错误"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git 推送錯誤"
}
}
}
},
"Git repository already exists, delete it and clone again??" : {
"extractionState" : "manual",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git repository already exists, delete it and clone again??"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git repozitář už existuje, chcete ho smazat a klonovat znovu?"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git repository already exists, delete it and clone again??"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git repository already exists, delete it and clone again??"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Le dépôt Git existe déjà, voulez-vous le supprimer et le cloner à nouveau ??"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git repository already exists, delete it and clone again??"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "गिट रिपोजिटरी पहले से मौजूद है, इसे हटाएँ और फिर से क्लोन करें??"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git repository already exists, delete it and clone again??"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git repository already exists, delete it and clone again??"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git repository already exists, delete it and clone again??"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git repository already exists, delete it and clone again??"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "O repositório Git já existe, apagar-lo e clona-lo novamente??"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git repository already exists, delete it and clone again??"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git-репозиторий уже существует, удалить его и клонировать заново?"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git deposu zaten var, silinip tekrar klonlansın mı?"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git repository already exists, delete it and clone again??"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git 存储库已存在,请将其删除并再次克隆??"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git 儲存庫已存在,是否刪除並重新複製?"
}
}
}
},
"Hide Note List" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "إخفاء قائمة الملاحظات"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Skrýt seznam poznámek"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notizliste ausblenden"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ocultar notas"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Masquer la liste des notes"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הסתר רשימת הערות"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नोट सूची छिपाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nascondi l'elenco delle note"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ノート リストを非表示"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "메모 목록 숨기기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verbergen notitielijst"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ocultar lista de notas"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ocultar lista de notas"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Спрятать список заметок"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Not Listesini Gizle"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Приховати нотатки"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "隐藏笔记列表"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "隱藏筆記列表"
}
}
}
},
"Hide Sidebar" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "اخفاء الشريط الجانبي"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Skrýt boční panel"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Seitenleiste ausblenden"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ocultar barra lateral"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Masquer la barre latérale"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הסתר סרגל צד"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "साइडबार छिपाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nascondi sidebar"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "サイドバーを隠す"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "사이드바 숨기기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verbergen zijbalk"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ocultar menu lateral"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ocultar barra lateral"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Спрятать сайдбар"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kenar Çubuğunu Gizle"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Приховати сайдбар"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "隐藏边栏"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "隱藏側邊欄"
}
}
}
},
"History" : {
"comment" : "File Menu",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تاريخ"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Historie"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Die geschichte"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Historia"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Historique"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "היסטוריה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "इतिहास"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cronologia"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "履歴"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "변경 이력"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Geschiedenis"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Histórico"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Histórico"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "История"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Geçmiş"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Історія"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "笔记历史版本"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "歷史記錄"
}
}
}
},
"iCloud Drive" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Drive iCloud"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud 云盘"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud 雲碟"
}
}
}
},
"Import" : {
"comment" : "File Menu",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "استيراد"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Importovat"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Importieren"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Importar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Importer"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "ייבא"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "आयात"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Importa"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "取り込む..."
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "가져오기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Importeren"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Importar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Importar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Импорт"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "İçe aktar"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Імпортувати"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "导入"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "匯入"
}
}
}
},
"Inbox" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "الوارد"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Příchozí"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Posteingang"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Entrada"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Boîte de réception"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "תיבת דואר נכנס"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "इनबॉक्स"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "In Entrata"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "未整理"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Inbox"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Postvak In"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Inbox"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Caixa de entrada"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Входящие"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Gelen kutusu"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вхідні"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "收集箱"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "收件匣 "
}
}
}
},
"Libgit2 error" : {
"extractionState" : "manual",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Libgit2 error"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Chyba libgit2"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Libgit2 error"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Libgit2 error"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Erreur libgit2"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Libgit2 error"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "Libgit2 त्रुटि"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Libgit2 error"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Libgit2 error"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Libgit2 error"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Libgit2 error"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Libgit2 error"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Libgit2 error"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ошибка libgit2"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Libgit2 hatası"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Libgit2 error"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "Libgit2 错误"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "Libgit2 錯誤"
}
}
}
},
"Libgit2 error: (code)" : {
"extractionState" : "manual",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Libgit2 خطأ: (code)"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Chyba libgit2: (code)"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Libgit2 fehler: (code)"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Libgit2 error: (code)"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Erreur Libgit2 : (code)"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Libgit2 שְׁגִיאָה: (code)"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "Libgit2 त्रुटि: (कोड)"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Libgit2 errore: (code)"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Libgit2 エラー: (code)"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Libgit2 오류: (code)"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Libgit2 error: (code)"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Libgit2 error: (code)"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Libgit2 erro: (code)"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ошибка libgit2: (код)"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Libgit2 hatası : (code)"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Libgit2 помилка: (code)"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "Libgit2 错误: (code)"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "Libgit2 錯誤:(代碼)"
}
}
}
},
"Link" : {
"extractionState" : "migrated",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "رابط"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Odkaz"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Link"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Enlace"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lien"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "קישור"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "लिंक"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Link"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "リンク"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "링크"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Link"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Link"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ligação"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ссылка"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bağlantı"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Посилання"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "链接"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "連結"
}
}
}
},
"Lock" : {
"comment" : "File Menu",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "قفل"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zamknout"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sperren"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cerrar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verrouiller"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "נעל"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "लॉक करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Serratura"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ロック"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "자물쇠"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lock"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloquear"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Trancar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заблокировать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kilit"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заблокувати"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "上锁"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "鎖定"
}
}
}
},
"Lock All Encrypted" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "قفل جميع المشفرة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zamknout všechny zašifrované"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Alle verschlüsselte sperren"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloquar todas las encriptadas"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verrouiller les documents chiffrés"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "נעל פתקים מוצפנים"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "सभी एन्क्रिप्टेड लॉक करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Blocca tutte le note criptate"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ロックされたノートをすべて閉じる"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "모든 암호화 된 노트 잠금"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vergrendel alle versleutelde"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloquear todos os criptografados"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloquear Todos os Criptografados"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заблокировать все секретные"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tüm Şifrelenmişleri Kilitle"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заблокувати всі секретні"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "锁定所有加密的笔记"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "鎖定所有已加密項目"
}
}
}
},
"Lock Folder" : {
"comment" : "Menu Library",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "قفل المجلد"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zamknout složku"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordner sperren"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloquear carpeta"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verrouiller le dossier"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "נעל תיקייה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "फ़ोल्डर लॉक करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Blocca cartella"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "フォルダロック"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "자물쇠"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Map vergrendelen"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloquear pasta"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloquear pasta"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заблокировать директорию"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Klasörü Kilitle"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заблокувати директорію"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "锁定文件夹"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "鎖定資料夾"
}
}
}
},
"Locked" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Locked"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zamčeno"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Abgeschlossen"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloqueado"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verrouillé"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Locked"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "लॉक की गई"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloccato"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ロック"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "잠김"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Gesloten"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloqueado"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloqueado"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заблокированный"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kilitli"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Замкнено"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "锁定"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "鎖定"
}
}
}
},
"Make Link" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Make Link"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vytvořit odkaz"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Make Link"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Make Link"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Créer un Lien"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Make Link"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "लिंक बनाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Make Link"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Make Link"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Make Link"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Make Link"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Criar Link"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Make Link"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сделать ссылку"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bağlantı Yap"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Make Link"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "建立链接"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "建立連結"
}
}
}
},
"Master password:" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "كلمة المرور الاساسية"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hlavní heslo:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Master Passwort:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Contraseña maestra:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mot de passe maître :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "סיסמה ראשית:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "मास्टर पासवर्ड:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Master password:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "マスターパスワード:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "마스터 암호:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hoofdwachtwoord:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Senha mestre:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Palavra-passe mestra:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Мастер пароль:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ana şifre:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Мастер пароль"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "管理员密码:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "主密碼:"
}
}
}
},
"Move" : {
"comment" : "File Menu\nMenu",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "نقل"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Přesunout"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verschieben"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mover"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Déplacer"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "העבר"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "स्थानांतरण"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sposta"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "移動"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "이동"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verplaats"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mover"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mover"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Переместить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Taşı"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перемістити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "移动"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "移動"
}
}
}
},
"Move error" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "نقل خطأ"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Chyba při přesouvání"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fehler beim Verschieben"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Error de movimiento"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Erreur de déplacement"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "שגיאת העברה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "स्थानांतरण त्रुटि"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Errore di spostamento"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "移動エラー"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "이동 오류"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fout bij verplaatsen"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Erro ao mover"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Erro de deslocação"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ошибка перемещения"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Taşıma hatası"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Помилка переміщення"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "移动错误"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "移動錯誤"
}
}
}
},
"New" : {
"comment" : "File Menu",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "جديد"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nový"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Neu"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nuevo"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nouvelle"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "חדש"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नया"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nuovo"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "新規"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "새로운 노트"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nieuw"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Novo"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Novo"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Создать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yeni"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Нова нотатка"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "新建"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "新增"
}
}
}
},
"New folder" : {
"extractionState" : "manual",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "مجلد جديد"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nová složka"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Neuer Ordner"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nueva carpeta"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nouveau dossier"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "תיקיה חדשה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नया फ़ोल्डर"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nuova cartella"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "新規フォルダ"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "새로운 폴더"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nieuwe map"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nova pasta"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nova pasta"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Создать директорию"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yeni Dosya"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Нова директорія"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "新建文件夹"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "新增資料夾"
}
}
}
},
"New Folder" : {
"comment" : "Menu Library",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "إنشاء مجلد"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vytvořit složku"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Neuer Ordner"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Crear carpeta"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nouveau dossier"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "תיקיה חדשה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "फोल्डर बनाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nuova cartella"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "フォルダ作成"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "새로운 폴더"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Map aanmaken"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Criar pasta"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Criar pasta"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Создать директорию"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Klasör Oluştur"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Нова директорія"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "创建文件夹"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "新增資料夾"
}
}
}
},
"New Note" : {
"comment" : "File Menu",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "ملاحظة جديدة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nová poznámka"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Neue Notiz"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nueva nota"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nouvelle note"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הערה חדשה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नया नोट"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nuova nota"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "新規ノート"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "새 메모"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nieuwe notitie"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nova nota"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nova nota"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Новая заметка"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yeni Not"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Нова нотатка"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "新建笔记"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "新增筆記"
}
}
}
},
"New Note in New Window" : {
"comment" : "File Menu",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "ملاحظة جديدة في نافذة جديدة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nová poznámka v novém okně"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Neue Notiz in neuem Fenster"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nueva nota en una ventana nueva"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nouvelle note dans une nouvelle fenêtre"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הערה חדשה בחלון חדש"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नई विंडो में नया नोट"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nuova nota in una nuova finestra"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "新規ノートを新規ウィンドウで開く"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "새 창에서 새 메모 열기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nieuwe notitie in nieuw venster"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nova nota em nova janela"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nova nota numa nova janela"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Новая заметка в новом окне"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yeni Pencerede Yeni Not"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Нова нотатка у новому вікні"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "在新窗口中新建笔记"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "在新視窗中新增筆記"
}
}
}
},
"New project" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "مشروع جديد"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nový projekt"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Neues Projekt"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nuevo proyecto"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nouveau projet"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "פרויקט חדש"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नया प्रोजैक्ट"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nuovo progetto"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "新規プロジェクト"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "새로운 프로젝트"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nieuw project"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Novo projeto"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Novo projeto"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Новая директория"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yeni Proje"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Нова директорія"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "新建项目"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "新增專案"
}
}
}
},
"No" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "No"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ne"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "No"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "No"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Non"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "לא"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नहीं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "No"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "いいえ"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "아니"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "No"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Não"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Não"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Нет"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hayır"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ні"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "否"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "否"
}
}
}
},
"None Selected" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "None Selected"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nic nevybráno"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Keine ausgewählt"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ninguno Seleccionado"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aucune sélection"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "None Selected"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कोई भी नहीं चुना गया"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nessuno selezionato"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "選択なし"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "선택되지 않음"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Geen geselecteerd"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nada selecionado"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nenhum selecionado"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Не выбрано"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Seçilmedi"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Не вибрано"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "无选择"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "未選取任何項目"
}
}
}
},
"Note with name \"%@\" already exists in selected directory." : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "ملاحظة بالاسم \"%@\" موجودة بالفعل في المجلد المحدد."
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Poznámka s názvem „%@“ už ve vybrané složce existuje."
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Note with name \"%@\" already exists in selected directory."
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ya existe una carpeta nombrada '%@' en el directorio seleccionado."
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "La note avec le nom \"%@\" existe déjà dans le répertoire sélectionné."
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "פתק בשם \"%@\" כבר קיים בתיקיה הנבחרת."
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "चयनित निर्देशिका में \"%@\" नाम वाला नोट पहले से मौजूद है।"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "La nota con il nome \"%@\" già esiste nella cartella selazionata."
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ノート \"%@\" は指定したフォルダにすでに存在しています"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "이름이 있는 메모 \"%@\" 선택한 디렉토리에 이미 존재합니다."
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Opmerking met de naam \"%@\" bestaat al in de geselecteerde map."
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nota com o nome \"%@\" já existe na pasta selecionada."
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Já existe uma nota com o nome \"%@\" no directório selecionado."
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заметка с названием \\\"%@\\\" уже существует в выбранной директории."
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Seçilen dizinde \"%@\" adlı not zaten mevcut."
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Нотатка з назвою \"%@\" вже існує у вибраной директорії."
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "名称为 \"%@\" 的笔记已存在于所选目录中。"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "所選目錄中已存在名為\"%@\" 的筆記。"
}
}
}
},
"Notes" : {
"comment" : "Sidebar label",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "ملاحظات"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Poznámky"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notizen"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notas"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notes"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "פתקים"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नोट"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Note"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "すべて"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "모든 노트"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notities"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notas"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notas"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заметки"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notlar"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Нотатки"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "所有笔记"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "筆記"
}
}
}
},
"OK" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "موافق"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "OK"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "OK"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "OK"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "OK"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "אישור"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "ठीक है"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "OK"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "OK"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "확인"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "OK"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "OK"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "OK"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "OK"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tamam"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "OK"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "好的"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "確定"
}
}
}
},
"Open External" : {
"comment" : "File Menu",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "فتح خارجي"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Otevřít externí"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "In externem Editor öffnen"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Abrir externo"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ouvrir en externe"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "פתח חיצוני"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "बाहरी खोलें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Apri esternamente"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "開く…"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "외부에서 열기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Open extern"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Abrir External"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Abrir externamente"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Внешний редактор"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Açık Harici"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Відкрити зовні"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "打开外部"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "開啟外部連結"
}
}
}
},
"Open note" : {
"comment" : "Document opened",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "افتح الملاحظة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Otevřená poznámka"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notiz öffnen"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Abrir nota"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Note ouverte"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "פתח פתק"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नोट खोलें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Apri nota"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "開かれたノート"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "메모 열기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notitie openen"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Abrir nota"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Abrir nota"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Открыть заметку"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notu Aç"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Відкрити нотатку"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "打开笔记"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "開啟筆記"
}
}
}
},
"Open Note in New Window" : {
"comment" : "File Menu",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "فتح الملاحظة في نافذة جديدة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Otevřít poznámku v novém okně"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notiz in neuem Fenster öffnen"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Abrir nota en una ventana nueva"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ouvrir la note dans une nouvelle fenêtre"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "פתח הערה בחלון חדש"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नई विंडो में नोट खोलें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Apri nota in una nuova finestra"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ノートを新規ウィンドウで開く"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "메모 새 창에서 열기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notitie openen in nieuw venster"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Abrir nota em nova janela"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Abrir nota numa nova janela"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Открыть заметку в новом окне"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notu Yeni Pencerede Aç"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Відкрити нотатку у новому вікні"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "在新窗口中打开笔记"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "在新視窗中開啟筆記"
}
}
}
},
"Otherwise, the database of your notes will be available at: " : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "وإلا، ستكون قاعدة بيانات الملاحظات متوفرة على: "
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vaše databáze poznámek bude jinak k dispozici zde: "
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Otherwise, the database of your notes will be available at: "
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "De lo contrario la base de datos de tus notas estará disponible en: "
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sinon, la base de données de vos notes sera disponible sur : "
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "אחרת, אחסון פתקיך יהיה נגיש ב:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "अन्यथा, आपके नोट्स का डेटाबेस यहां उपलब्ध होगा:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Altrimenti, il database delle tue note sarà disponibile su: "
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "あるいは、データベースは次の場所で利用できます: "
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "그렇지 않으면 메모 데이터베이스를 다음에서 사용할 수 있습니다."
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Otherwise, the database of your notes will be available at: "
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Caso contrário, a base de dados das suas notas estará disponível em: "
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "De outra forma, os dados das suas notas estarão disponíveis em:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "В противном случае база данных заметок будет доступна по адресу: "
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aksi takdirde notlarınızın veritabanına şu adresten ulaşabilirsiniz:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Інакше база даних ваших нотаток буде доступна за адресою: "
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "否则,您的笔记数据库将在以下位置可用:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "否則,您的筆記資料庫將位於:"
}
}
}
},
"Password:" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "كلمة المرور:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Heslo:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Passwort:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Contraseña:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mot de passe :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "סיסמה:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पासवर्ड"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Password:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "パスワード:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "비밀번호:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Wachtwoord:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Senha:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Palavra-passe:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Пароль:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Şifre:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Пароль:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "密码:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "密碼:"
}
}
}
},
"Path not available" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "المسار غير متوفر"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cesta není k dispozici"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Path not available"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Carpeta no disponible"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Chemin non disponible"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הנתיב אינו זמין"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पथ उपलब्ध नहीं है"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Percorso non disponibile"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "無効なパスです"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "경로를 사용할 수 없음"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pad niet beschikbaar"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Caminho indisponível "
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Caminho não disponível"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Путь недоступен"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yol mevcut değil"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Шлях недоступний"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "路径不可用"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "路徑無法使用"
}
}
}
},
"Pin" : {
"comment" : "File Menu",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "دبوس"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Připnout"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fixieren"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Anclar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Épingler"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הצמד"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पिन"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fissa"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "メモをピンで固定"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "고정"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pin"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pin"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fixar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Прикрепить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pin"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Закріпити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "置顶"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "釘選"
}
}
}
},
"Please enter image title:" : {
"comment" : "Edit area",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "الرجاء إدخال عنوان الصورة:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zadejte popis obrázku:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Geben Sie die Bildbezeichnung ein:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Por favor, introduce un título para la imagen:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Veuillez saisir le titre de l'image :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "נא הכנס כותרת תמונה:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कृपया छवि शीर्षक दर्ज करें:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Inserisci il titolo dell'immagine:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "イメージタイトルを入力:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "이미지 제목을 입력하십시오:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Voer a.u.b. afbeeldingstitel in:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Por favor, insira um título na imagem:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Por favor insira o título da imagem:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Пожалуйста, введите заголовок изображения:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Resim başlığını girin"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заголовок зображення:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "请输入图片标题:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "請輸入圖片標題:"
}
}
}
},
"Please enter password for current note" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "الرجاء إدخال كلمة المرور للملاحظة الحالية"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zadejte heslo k této poznámce"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Geben Sie das Passwort für die aktuelle Notiz ein"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Por favor, introduce una contraseña para la nota"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Veuillez entrer le mot de passe pour la note actuelle"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "נא הכבס סיסמה לפתק הנוכחי"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कृपया वर्तमान नोट के लिए पासवर्ड दर्ज करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Inserisci la password per la nota corrente"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "現在開いているノートのためのパスワードを入力"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "노트 암호를 입력하십시오"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Voer a.u.b. wachtwoord voor huidige notitie in:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Por favor, insira uma senha para nota atual"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Por favor insira a palavra-passe para a nota atual"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Введите пароль для текущей заметки"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lütfen güncel not için şifreyi giriniz"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Будь ласка, введіть пароль для нотатки"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "请输入当前笔记的密码"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "請輸入目前筆記的密碼"
}
}
}
},
"Please enter project name:" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "الرجاء إدخال اسم المشروع:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zadejte název projektu:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Geben Sie den Projektname ein:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Por favor, introduce un nombre para el proyecto:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Veuillez saisir le nom du projet :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "נא הכנב שם פרויקט:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कृपया प्रोजैक्ट का नाम दर्ज करें:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Inserisci il nome del progetto:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "プロジェクト名を入力:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "프로젝트 이름을 입력하십시오:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Voer a.u.b. projectnaam in:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Por favor, insira um nome no projeto:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Por favor insira o nome do projeto:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Пожалуйста, введите название директории:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lütfen proje adını giriniz:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Будь ласка, введіть назву директорії:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "请输入项目名称:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "請輸入專案名稱:"
}
}
}
},
"Please enter tag name:" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "الرجاء إدخال اسم الوسم:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zadejte jméno značky:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bitte geben Sie den Tag-Namen ein:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Por favor, introduce un nombre para la etiqueta:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Veuillez saisir le nom de l’étiquette :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "נא הכנס שם תג:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कृपया टैग नाम दर्ज करें:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Inserisci il nome del tag:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "タグ名を入力:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "태그 이름을 입력하세요:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Voer de tagnaam in:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Por favor, insira um nome na tag:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Por favor insira o nome da etiqueta:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Введите название тега:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lütfen etiket adını girin:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Будь ласка, введіть назву тегу:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "请输入标签名称:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "請輸入標籤名稱:"
}
}
}
},
"Please enter tags (comma separated):" : {
"comment" : "Menu",
"extractionState" : "manual",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "رجاءً ادخل وسوم (مفصولة بفارزة)"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zadejte značky (oddělené čárkami):"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Geben Sie Tags ein (durch Kommas getrennt):"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Por favor, introduce las etiquetas (separadas por comas):"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Veuillez saisir des étiquettes (séparées par des virgules) :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "נא הכנס תגים (מופרדים בפסיק):"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कृपया टैग दर्ज करें (अल्पविराम से अलग करके):"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Inserisci i tag (separati da virgole):"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "タグを入力(コンマ区切り):"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "태그를 입력하십시오(콤마로 구분):"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Voer a.u.b. tags (kommagescheiden) in:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Por favor, insira tags (separadas por vírgulas):"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Por favor insira as etiquetas (separadas por vírgulas):"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Пожалуйста введите теги (через запятую):"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lütfen etiketleri girin (virgülle ayırarak):"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Будь ласка, введіть теги (розділити комою):"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "请输入标签(使用英文逗号分隔):"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "請輸入標籤(以逗號分隔):"
}
}
}
},
"Please init git repository before (Preferences -> Git -> Init/commit)" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Please init git repository before (Preferences -> Git -> Init/commit)"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nejprve inicializujte repozitář (Nastavení > Git > Init/commit)"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Please init git repository before (Preferences -> Git -> Init/commit)"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Please init git repository before (Preferences -> Git -> Init/commit)"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "S’il vous plait, initialiser le dépôt git avant (Preferences -> Git -> Init/commit)"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Please init git repository before (Preferences -> Git -> Init/commit)"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कृपया पहले गिट रिपोजिटरी प्रारंभ करें (प्राथमिकताएं -> गिट -> आरंभ/कमिट)"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Please init git repository before (Preferences -> Git -> Init/commit)"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Please init git repository before (Preferences -> Git -> Init/commit)"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Please init git repository before (Preferences -> Git -> Init/commit)"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Please init git repository before (Preferences -> Git -> Init/commit)"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Por favor, inicie o repositório git antes (Preferências -> Git -> Init/commit)"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Please init git repository before (Preferences -> Git -> Init/commit)"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Пожалуйста, предварительно инициируйте git-репозиторий (Preferences -> Git -> Init/commit)."
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lütfen git deposunu başlatmadan önce (Tercihler -> Git -> Başlat/gönder)"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Please init git repository before (Preferences -> Git -> Init/commit)"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "Please init git repository before (Preferences -> Git -> Init/commit)"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "請先初始化 Git 儲存庫 (偏好設定 -> Git -> 初始化/提交)"
}
}
}
},
"Please select private and public key" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "الرجاء تحديد مفتاح خاص وعام"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vyberte prosím veřejný a soukromý klíč"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bitte wählen Sie privaten und öffentlichen Schlüssel aus"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Seleccione la clave pública y privada"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Veuillez sélectionner une clé privée et une clé publique"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "אנא בחר מפתח פרטי וציבורי"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कृपया निजी और सार्वजनिक कुंजी चुनें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Seleziona la chiave privata e pubblica"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "秘密鍵と公開鍵を選択してください"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "개인 키와 공개 키를 선택하세요."
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Selecteer a.u.b. privé en openbare sleutel"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Por favor, selecione uma chave privada e pública"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Por favor, selecione a chave privada e pública"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Пожалуйста, выберите закрытый и открытый ключ"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lütfen özel ve genel anahtarı seçin"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Будь ласка, оберіть приватний та публічний ключ"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "请选择私钥和公钥"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "請選擇私鑰和公鑰"
}
}
}
},
"Please select private key" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "الرجاء تحديد المفتاح الخاص"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vyberte prosím soukromý klíč"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bitte wählen Sie den privaten Schlüssel aus"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Por favor seleccione clave privada"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Veuillez sélectionner la clé privée"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "אנא בחר מפתח פרטי"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कृपया निजी कुंजी चुनें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Seleziona la chiave privata"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "秘密鍵を選択してください"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "개인 키를 선택하십시오"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Selecteer a.u.b. privésleutel"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Por favor, insira uma chave privada"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Selecione a chave privada"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Выберите закрытый ключ"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lütfen özel anahtarı seçin"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Будь ласка, виберіть приватний ключ"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "请选择私钥"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "請選擇私鑰"
}
}
}
},
"Please try again" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "حاول مرة اخرى"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zkuste to znovu"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Versuchen Sie bitte nochmal"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Por favor intenta de nuevo"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Veuillez réessayer"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "נסה שוב"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कृपया पुन: प्रयास करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Per favore riprova"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "もう一度試してください"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "다시 시도하십시오"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Probeer het a.u.b. opnieuw"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Por favor, tente novamente"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Volte a tentar por favor"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Пожалуйста, попробуйте ещё раз"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lütfen tekrar deneyin"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Буль ласка, спробуйте знову"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "请再试一次"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "請再試一次 "
}
}
}
},
"Preferences" : {
"comment" : "Localizable.strings\n FSNotes\n \n Created by Oleksandr Glushchenko on 7/4/18.\n Copyright © 2018 Oleksandr Glushchenko. All rights reserved.",
"extractionState" : "migrated",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "التفضيلات"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Předvolby"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Einstellungen"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Preferencias"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Préférences"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "העדפות"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "प्राथमिकताएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Preferenze"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "設定"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "환경설정"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Voorkeuren"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Preferências"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Preferências"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Настройки"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tercihler"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Налаштування"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "偏好设置"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "偏好設定"
}
}
}
},
"Print" : {
"comment" : "File Menu",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "طباعة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tisknout"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Drucken"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Imprimir"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Imprimer"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הדפס"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "प्रिंट"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Stampa"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "印刷"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "프린트"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Druk af"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Imprimir"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Imprimir"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Печать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yazdır"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Роздрукувати"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "打印"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "列印"
}
}
}
},
"Quit FSNotes" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "اغلاق FSNotes"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ukončit FSNotes"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes beenden"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Salir de FSNotes"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Quitter FSNotes"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "סיים את FSNotes"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes बंद करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Esci da FSNotes"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotesを終了"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes 종료"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Stop FSNotes"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sair do FSNotes"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sair do FSNotes"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Выйти из FSNotes"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes'tan çıkın"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Завершити роботу FSNotes"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "退出FSNotes"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "結束 FSNotes"
}
}
}
},
"Recents" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "الحديثة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nedávné"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Letzte"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Recientes"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Récents"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "אחרונים"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "हाल ही का"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Recenti"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "最近"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "최근"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Recente"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Recentes"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Recentes"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Недавние"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Arananlar"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Останні"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "最近"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "最近項目"
}
}
}
},
"Recents Search" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "البحث الأخير"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hledat nedávné"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Neueste Suche"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Búqueda de Recientes"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Recherches récentes"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "חיפושים אחרונים"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "हाल की खोजें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ricerche Recenti"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "最近の検索"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "최근 검색"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Recent zoeken"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Buscas recentes"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Procurar Recentes"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Недавние запросы"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Son Arananlar"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Останні запити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "最近搜索"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "最近搜尋紀錄"
}
}
}
},
"Remove" : {
"comment" : "Delete menu",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "حذف"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Odebrat"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Löschen"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Borrar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Supprimer"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הסר"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "हटाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rimuovi"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "削除"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "삭제"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verwijder"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remover"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remover"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Удалить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kaldır"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Видалити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "移除"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "移除"
}
}
}
},
"Remove Link" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "حذف الرابط"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Odebrat odkaz"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remove Link"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Eliminar enlace"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Supprimer le lien"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הסר קישור"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "लिंक हटाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rimuovi Link"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "リンクを削除"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "링크 제거"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verwijder Link"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remover Link"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remover Ligação"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Удалить ссылку"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bağlantıyı Kaldır"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Видалити посилання"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "删除链接"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "移除連結"
}
}
}
},
"Remove note(s)" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "حذف ملاحظة/ملاحظات"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Odebrat poznámku/y"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notiz (en) entfernen"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Eliminar nota(s)"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Supprimer la(les) note(s)"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הסר פתקים"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नोट हटाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rimuovi nota/e"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ノートを削除"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "노트 삭제"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verwijder notitie(s)"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remover nota(s)"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Eliminar nota(s)"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Удалить заметки"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notu(ları) kaldır"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Видалити нотатку(ок)"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "移除笔记"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "移除筆記"
}
}
}
},
"Remove Tags" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "إزالة العلامات"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Odebrat značky"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tags entfernen"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Eliminar etiquetas"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Supprimer les étiquettes"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הסר תגים"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "टैग हटाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rimuovi tag"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "タグを削除"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "태그 제거"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verwijderen tags"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remover Tags"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remover Etiquetas"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Удалить теги"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Etiketleri Kaldır"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Видалити теги"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "删除标签"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "移除標籤"
}
}
}
},
"Rename" : {
"comment" : "File Menu",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "اعادة تسمية"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Přejmenovat"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Umbenennen"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renombrar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renommer"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "שנה שם"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नाम बदलें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rinomina"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "名前を変更"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "이름 변경"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hernoem"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renomear"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renomear"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Переименовать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yeniden isimlendir"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перейменувати"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "重命名"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "重新命名"
}
}
}
},
"Rename Folder" : {
"comment" : "Menu Library",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "اعادة تسمية المجلد"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Přejmenovat složku"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordner umbenennen"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renombar carpeta"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renommer le dossier"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "שנה שם תיקיה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "फ़ोल्डर का नाम बदलें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rinomina cartella"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "フォルダの名称変更"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "노트 이름 변경"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hernoem map"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renomear pasta"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renomear pasta"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Переименовать директорию"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Klasörü Yeniden Adlandır"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перейменувати директорію"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "重命名文件夹"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "重新命名資料夾"
}
}
}
},
"Rename Tag" : {
"comment" : "Menu Library",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "إعادة تسمية العلامة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Přejmenovat značku"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tag umbenennen"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renombar etiqueta"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renommer l’étiquette"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "שנה שם תג"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "टैग का नाम बदलें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rinomina tag"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "タグの名称変更"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "태그 이름 바꾸기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hernoemen tag"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renomear Tag"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renomear Etiqueta"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Переименовать тег"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Etiketi Yeniden Adlandır"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перейменувати тег"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "重命名标签"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "重新命名標籤"
}
}
}
},
"Rename Tags" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "إعادة تسمية العلامات"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Přejmenovat značky"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tags umbenennen"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renombar etiqueta"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renommer les étiquettes"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "שנה שמות תגים"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "टैग का नाम बदलें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rinomina tag"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "複数タグの名称変更"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "태그 이름 바꾸기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hernoemen tags"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renomear Tags"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renomear Etiquetas"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Переименовать теги"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Etiketleri Yeniden Adlandır"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перейменувати теги"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "重命名标签"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "重新命名標籤"
}
}
}
},
"Repository not found" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Repository not found"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Repozitář nenalezen"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Repository not found"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Repository not found"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dépôt non trouvé"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Repository not found"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "रिपोजिटरी नहीं मिली"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Repository not found"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Repository not found"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Repository not found"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Repository not found"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Repositório não encontrado"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Repository not found"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Репозиторий не найден"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Depo bulunamadı"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Репозиторій не знайдено"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "Repository not found"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "找不到儲存庫"
}
}
}
},
"Reveal in Finder" : {
"comment" : "File Menu\nMenu Library",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "فتح المجلد"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zobrazit ve Finderu"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "In Finder anzeigen"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar en el Finder"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Localiser dans le Finder"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הצג ב-Finder"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "Finder में दिखाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostra nel Finder"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Finderに表示"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Finder에서 보기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Toon in Finder"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar no Finder"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Realçar no Finder"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показать в Finder"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Finder'da göster"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показати в Finder"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "在Finder中显示"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "顯示於 Finder"
}
}
}
},
"Search" : {
"localizations" : {
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Buscar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Поиск"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ara"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Пошук"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "搜尋"
}
}
}
},
"Search and create" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "بحث و انشاء"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hledat a vytvořit"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Suchen und ersetzen"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Buscar y crear"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rechercher et créer"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "חיפוש ויצירה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "खोजें और बनाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cerca e crea"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "検索または新規作成"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "검색 및 추가"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zoek en creëer"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Busque e crie"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pesquisar e criar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Найти и создать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ara ve oluştur"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Знайти або створити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "搜索或创建(按下回车即可创建)"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "搜尋並建立"
}
}
}
},
"Search and Create" : {
"comment" : "File Menu",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "بحث وانشاء"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hledat a vytvořit"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Suchen und ersetzen"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Buscar y crear"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rechercher et créer"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "חיפוש יצירה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "खोजें और बनाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cerca e crea"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "検索または新規作成"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "검색 및 추가"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zoek en creëer"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pesquisar e criar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pesquisar e criar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Найти и создать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ara ve oluştur"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Знайти або створити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "搜索或创建(按下回车即可创建)"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "搜尋並建立"
}
}
}
},
"Settings" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "التفضيلات"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nastavení"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Einstellungen"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Preferencias"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Paramètres"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "העדפות"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "प्राथमिकताएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Preferenze"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "設定"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "환경설정"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Voorkeuren"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Configurações"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Preferências"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Настройки"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ayarlar"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Налаштування"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "偏好设置"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "設定"
}
}
}
},
"Show in Finder" : {
"extractionState" : "manual",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "فتح المجلد"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zobrazit ve Finderu"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordner anzeigen"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar carpeta"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Localiser dans le Finder"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הצג ב-Finder"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "Finder में दिखाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostra nel Finder"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Finderに表示"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Finder에서 보기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Toon in Finder"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar no Finder"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar no Finder"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показать в Finder"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bulucuda Göster"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показати в Finder"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "在访达中显示"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "在Finder中顯示"
}
}
}
},
"Show Note List" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "إظهار قائمة الملاحظات"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zobrazit seznam poznámek"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notizliste anzeigen"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar notas"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Afficher la liste des notes"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הצג רשימת הערות"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नोट सूची दिखाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostra l'elenco delle note"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ノート一覧を表示"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "메모 목록 표시"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tonen notitielijst"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar lista de notas"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar lista de notas"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показать список заметок"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Not Listesini Göster"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показати нотатки"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "显示笔记列表"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "顯示筆記列表"
}
}
}
},
"Show Options" : {
"comment" : "Menu Library",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "عرض الاعدادات"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zobrazit možnosti"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Einstellungen anzeigen"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ver configuración"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Afficher les options d'affichage"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הצג אפשרויות"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "विकल्प दिखाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostra opzioni vista"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "オプションを表示"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "보기 옵션"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Toon weergaveopties"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar as opções"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Desbloquear pasta"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показать опции"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Seçenekleri Göster"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показати параметри"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "显示视图选项"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "顯示選項"
}
}
}
},
"Show Sidebar" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "إظهار الشريط الجانبي"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zobrazit boční panel"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Seitenleiste anzeigen"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar barra lateral"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Afficher la barre latérale"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הצג סרגל צד"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "साइडबार दिखाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostra sidebar"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "サイドバーを表示"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "사이드바 표시"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tonen zijbalk"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar menu lateral"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar barra lateral"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показать сайдбар"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kenar Çubuğunu Göster"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показати сайдбар"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "显示侧边栏"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "顯示側邊欄"
}
}
}
},
"Show view options" : {
"extractionState" : "manual",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "عرض الاعدادات"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Volby zobrazení"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Einstellungen anzeigen"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ver configuración"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Afficher les options d'affichage"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הצג אפשרויות תצוגה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "दृश्य विकल्प दिखाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostra opzioni vista"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "表示オプションを表示"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "보기 옵션"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Toon weergaveopties"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar opções de visualização"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar opções de visualização"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Настроить вид"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Görünüm seçeneklerini göster"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Налаштування вигляду"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "显示视图选项"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "顯示方式選項"
}
}
}
},
"Sort by" : {
"comment" : "View menu",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "صنف حسب"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Řadit podle"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sortiere nach"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordenar por"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Trier par"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "מיין לפי"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "इसके अनुसार क्रमबद्ध करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordina per"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "表示順序"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "다음으로 정렬"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sorteer op"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordernar por"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordenar por"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сортировать по"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sırala"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сортувати за"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "排序方式"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "排序方式"
}
}
}
},
"SSH error" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "SSH خطأ"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Chyba SSH"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "SSH fehler"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "SSH error"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Erreur SSH"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "SSH שְׁגִיאָה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "SSH त्रुटि"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "SSH errore"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "SSH エラー"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "SSH 오류"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "SSH fout"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "SSH error"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "SSH erro"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ошибка SSH"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "SSH hatası"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "SSH помилка"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "SSH error"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "SSH 錯誤"
}
}
}
},
"Tags" : {
"comment" : "Sidebar label",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "الوسوم"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Značky"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tags"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Etiquetas"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Étiquettes"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "תגים"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "टैग"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tag"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "タグ"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "태그"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tags"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tags"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Etiquetas"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Теги"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Etiketler"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Теги"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "标签"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "標籤"
}
}
}
},
"This action cannot be undone." : {
"comment" : "Delete menu",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "هذا الاجراء غير قابل للرجوع"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tuto akci nelze odvolat."
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Diese Aktion kann nicht rückgängig gemacht werden"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Esta operación no se puede deshacer."
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cette action ne peut pas être annulée."
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "לא ניתן לבטל פעולה זו."
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "यह क्रिया पूर्ववत नहीं की जा सकती।"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Questa azione non può essere annullata."
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "このアクションは取り消しできません。"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "이 작업은 취소할 수 없습니다."
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Deze actie kan niet ongedaan gemaakt worden."
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Essa ação não pode ser desfeita."
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Esta ação não pode ser revertida."
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Это действие не может быть отменено."
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bu eylem geri alınamaz."
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Цю дію неможливо відмінити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "此操作无法撤消。"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "此動作無法復原。"
}
}
}
},
"Todo" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "قائمة المهام"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Úkoly"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Todo"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pendientes"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tâches"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "מטלות"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "टुडू"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Da Fare"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "タスク"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "할 일"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Te Doen"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "A fazer"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tarefa"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Задачи"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yapılacak"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Завдання"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "待办事项"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "待辦事項"
}
}
}
},
"Toggle preview" : {
"extractionState" : "manual",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تبديل معاينة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Přepnout náhled"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vorschau umschalten"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cambiar previsualización"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Activer/désactiver l'aperçu"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הצג/הסתר תצוגה מקדימה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पूर्वावलोकन टॉगल करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Attiva / disattiva anteprima"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "プレビューを表示/非表示"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "미리보기 토글"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Wissel voorvertoning"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Alterar pré-visualização"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Alternar pré-visualização"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Переключить предпросмотр"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Önizlemeyi aç/kapat"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Переключити перегляд"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "切换预览"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "切換預覽"
}
}
}
},
"Trash" : {
"comment" : "Sidebar label",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "الملهملات"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Koš"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Papierkorb"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Papelera"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Corbeille"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "פח אשפה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कूडा"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cestino"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ゴミ箱"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "휴지통"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Prullenmand"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lixo"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lixo"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Корзина"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Çöp Kutusu"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сміття"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "回收站"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "垃圾桶"
}
}
}
},
"Unlink External Folder" : {
"comment" : "Menu Library",
"localizations" : {
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Desvincular carpeta externa"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Отвязать внешнюю папку"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Harici Klasörü Bağlantısını Kaldır"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Від'єднати зовнішню папку"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "解除外部資料夾連結"
}
}
}
},
"Unlock" : {
"comment" : "File Menu",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "الغاء القفل"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Odemknout"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Freischalten"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Desbloquear"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ouvrir"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "פתח"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "अनलॉक"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sbloccare"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ロック解除"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "잠금 해제"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ontgrendelen"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Desbloqueado"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Desbloquear"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Разблокировать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kilidi Aç"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Розблокувати"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "解锁"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "解鎖"
}
}
}
},
"Unlock Folder" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "فتح المجلد"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Odemknout složku"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordner entsperren"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Desbloquear carpeta"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Déverrouiller le dossier"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "בטל נעילת תיקייה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "फ़ोल्डर अनलॉक करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sblocca cartella"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "フォルダロック解除"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "폴더 잠금 해제"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Map ontgrendelen"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Desbloquear pasta"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Desbloquear pasta"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Разблокировать директорию"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Klasörü Kilidini Aç"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Розблокувати директорію"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "解锁文件夹"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "解鎖資料夾"
}
}
}
},
"Unpin" : {
"comment" : "File Menu",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "إلغاء التثبيت"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Odepnout"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Loslösen"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Desanclar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Désépingler"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "בטל הצמדה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "अनपिन"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sblocc"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ピン固定の解除"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "고정 해제"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "VerwijderPin"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Desafixar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Soltar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Открепить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sabitlemeyi kaldır"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Відкріпити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "取消置顶"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "取消釘選"
}
}
}
},
"Untagged" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "بدون علامات"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Neoznačené"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ungetaggt"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sin etiquetar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Non étiqueté"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "ללא תגים"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "बिना टैग"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Senza Tag"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "タグ無し"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "태그가 없는"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Niet gelabeld"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sem tags"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sem etiqueta"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Без тегов"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Etiketsiz"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Без тегів"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "无标签"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "未標籤 "
}
}
}
},
"Untitled Note" : {
"comment" : "Untitled Note",
"extractionState" : "migrated",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "ملاحظة بدون عنوان"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Poznámka bez názvu"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Unbenannte Notiz"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nota sin título"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Note sans titre"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "פתק ללא שם"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "शीर्षक रहित नोट"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nota senza titolo"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "名称未設定のノート"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "무제"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Naamloze notitie"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nota sem título"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nota sem título"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Без названия"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Başlıksız Not"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Без назви"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "无标题"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "未命名筆記"
}
}
}
},
"Update Web Page" : {
"comment" : "File Menu",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تحديث صفحة الويب"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aktualizovat webovou stránku"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Geteilte aktualisieren"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Actualizar página web"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mettre à jour la page Web"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "עדכן את דף האינטרנט"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "वेब पेज अपडेट करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aggiorna la pagina web"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web ページの更新"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "웹 페이지 업데이트"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Webpagina bijwerken"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Update página Web"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Atualizar página da Web"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Обновить веб-страницу"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web Sayfasını Güncelle"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Оновити веб-сторінку"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "更新网页"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "更新網頁"
}
}
}
},
"Upload error" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Upload error"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Chyba při nahrávání"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Upload error"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Upload error"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Erreur d'envoi de données"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Upload error"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "अपलोड त्रुटि"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Upload error"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Upload error"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Upload error"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Upload error"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Upload error"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Upload error"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ошибка загрузки"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yükleme hatası"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Upload error"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "上传错误"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "上傳錯誤"
}
}
}
},
"URL has been copied to clipboard" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تم نسخ الرابط"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Adresa URL zkopírována do schránky"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "URL wurde in die Zwischenablage kopiert"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "El enlace se ha copiado al portapapeles"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "L'URL a été copiée dans le presse-papiers"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הכתובת הועתקה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "URL को क्लिपबोर्ड पर कॉपी कर दिया गया है"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "L'URL è stato copiato negli appunti"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "クリップボードにURLがコピーされました"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "URL이 클립보드에 복사되었습니다"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "URL is gekopieerd naar klembord"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "URL copiado para a área de transferência"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Endereço URL foi copiado para a área de transferência"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ссылка была скопирована в буфер обмена"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "URL panoya kopyalandı"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Посилання було скопійовано в буфер обміну"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "URL已复制到剪贴板"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "網址已複製到剪貼簿"
}
}
}
},
"Verify Password:" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "اكد كلمة المرور:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ověřit heslo:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Passwort bestätigen:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verificar contraseña:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vérifier le mot de passe :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "אמת את הסיסמה:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पासवर्ड को सत्यापित करें:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verifica password:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "パスワードの確認:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "비밀번호 확인:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Wachtwoord verifiëren:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verifique a senha:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verificar palavra-passe:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Повторить пароль:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Şifreyi Doğrula:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Підтвердіть пароль:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "验证密码:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "驗證密碼:"
}
}
}
},
"View" : {
"comment" : "Menu",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "عرض"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zobrazení"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ansicht"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Visualización"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Voir"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "תצוגה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "देखें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vista"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "表示"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "보기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Weergave"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Visualização"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vista"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вид"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Görünüm"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вид"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "视图"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "檢視"
}
}
}
},
"We are detect that you are install FSNotes from Mac App Store with default storage in iCloud Drive, do you want to move old database in iCloud Drive?" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "اكتشفنا أنك تقوم بتثبيت FSNotes من Mac App Store مع التخزين الافتراضي في iCloud Drive ، هل تريد نقل قاعدة البيانات القديمة في iCloud Drive؟"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Detekovali jsme, že jste nainstalovali FSNotes z Mac App Storu s výchozím úložištěm na iCloud Drive, chcete přesunout starou databázi na iCloud Drive?"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Wir stellen fest, dass Sie FSNotes aus dem Mac App Store mit Standardspeicher in iCloud Drive installiert haben. Möchten Sie die alte Datenbank in iCloud Drive verschieben?"
}
},
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "We have detected that you have installed FSNotes from Mac App Store with default storage in iCloud Drive, do you want to move old database into iCloud Drive"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Se ha detectado que la versión de FSNotes instalada es del Mac App Store, con almacenamiento por defecto en iCloud Drive. ¿Quieres mover la base de datos antigua a iCloud Drive?"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nous détectons que vous installez FSNotes depuis le Mac App Store avec le stockage par défaut dans iCloud Drive, voulez-vous déplacer l'ancienne base de données dans iCloud Drive ?"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "שמנו לב שהתקנת FSNotes מה-App Store עם אחסון ב-iCloud Drive. האם ברצונך להעביר את המאגר הקודם ל-iCloud Drive?"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "हमने पाया है कि आपने iCloud ड्राइव में डिफ़ॉल्ट स्टोरेज के साथ Mac App Store से FSNotes इंस्टॉल किया है, क्या आप पुराने डेटाबेस को iCloud ड्राइव में ले जाना चाहते हैं?"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Abbiamo rilevato che stai installando FSNotes dal Mac App Store con l'archiviazione predefinita in iCloud Drive, vuoi spostare il vecchio database in iCloud Drive?"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotesをMac App Storeからインストールし、iCloud Driveにデフォルトで保存していることがわかりますが、iCloud Driveにある古いデータベースを移動しますか?"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive에 기본 저장 공간이 있는 Mac App Store에서 FSNotes를 설치한 것으로 감지되었습니다. iCloud Drive에서 이전 데이터베이스를 옮기시겠습니까?"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "We hebben gedetecteerd dat je FSNotes hebt geïnstalleerd vanuit Mac App Store met standaard opslag in iCloud Drive. Wil je oude database verplaatsen naar iCloud Drive?"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Detectamos que está instalando o FSNotes da Mac App Store com armazenamento padrão no iCloud Drive, deseja mover o banco de dados antigo no iCloud Drive?"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Detectamos que está a instalar o FSNotes através da Mac App Store com o armazenamento por defeito no iCloud Drive, deseja mover a base de dados antiga para o iCloud Drive?"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Мы обнаружили, что вы установили FSNotes из Mac App Store с хранилищем по умолчанию в iCloud Drive. Хотите ли вы перенести старую базу данных в iCloud Drive?"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes'u Mac App Store'dan iCloud Drive'daki varsayılan depolama alanıyla yüklediğinizi tespit ettik, eski veritabanını iCloud Drive'a taşımak ister misiniz?"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ми виявили, що ви встановили FSNotes з Mac App Store із зберіганням за замовчуванням в iCloud Drive, хочете перенести стару базу даних в iCloud Drive?"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "我们检测到您是从 Mac App Store 安装的 FSNotes,数据默认存储在 iCloud 云盘,您想移动 iCloud 云盘中的旧数据库吗?"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "我們偵測到您從 Mac App Store 安裝了 FSNotes,且預設儲存空間為 iCloud 雲碟 。您是否要將舊的資料庫移動至iCloud 雲碟 ?"
}
}
}
},
"We can not move \"{DST_PATH}\" because this item already exist in selected destination." : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "لا يمكننا نقل \"{DST_PATH}\" لأن هذا العنصر موجود بالفعل في الوجهة المحددة."
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nelze přesunout „{DST_PATH}“, protože tato položka už ve vybraném cíli existuje."
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "We can not move \"{DST_PATH}\" because this item already exist in selected destination."
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "No se puede mover \"{DST_PATH}\" porque ya existe en el destino seleccionado."
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nous ne pouvons pas déplacer \"{DST_PATH}\" car cet élément existe déjà dans la destination sélectionnée."
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "לא ניתן להעביר \\\"{DST_PATH}\\\" מפני שקובץ באותו שם כבר קיים ביעד הנבחר."
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "हम \"{DST_PATH}\" को स्थानांतरित नहीं कर सकते क्योंकि यह आइटम पहले से ही चयनित गंतव्य में मौजूद है।"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Non possiamo spostare \"{DST_PATH}\" perché questo elemento esiste già nella destinazione selezionata."
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "移動先に同名のアイテムがすでに存在しているため、\\\"{DST_PATH}\\\"を移動できませんでした"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "이 항목이 선택한 대상에 이미 있으므로 \"{DST_PATH}\"을(를) 이동할 수 없습니다."
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "We can not move \"{DST_PATH}\" because this item already exist in selected destination."
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Não podemos mover \"{DST_PATH}\" porque este item já existe no destino selecionado."
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "É impossível mover \"{DST_PATH}\" porque este item já existe atualmente no destino seleccionado."
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Мы не можем переместить \\\\\\\"{DST_PATH}\\\\\\\", потому что этот путь уже существует в выбранном месте назначения."
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "\"{DST_PATH}\" öğesini taşıyamayız çünkü bu öğe seçili hedefte zaten mevcut."
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ми не можемо перемістити \\\"{DST_PATH}\\\", оскільки цей елемент вже існує у вибраному сховищі."
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "我们不能移动 \"{DST_PATH}\",因为这个项目已经存在于选定的目标处。"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "無法移動”{DST_PATH}”,因為選定的目的地已存在此項目。"
}
}
}
},
"Web" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "वेब"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "创建网页URL并打开"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "網頁"
}
}
}
},
"Web publishing error" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "خطأ في النشر على الويب"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Chyba zveřejnění na webu"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fehler bei der Webveröffentlichung"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Error de publicación web"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Erreur de publication Web"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "שגיאת פרסום באינטרנט"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "वेब प्रकाशन त्रुटि"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Errore di pubblicazione sul Web"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ウェブ公開エラー"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "웹 게시 오류"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fout bij webpublicatie"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "error de publicação Web"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Erro de publicação na Web"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ошибка веб-публикации"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web yayınlama hatası"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Помилка веб-публікації"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "网络发布错误"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "網頁發布錯誤"
}
}
}
},
"Wrong password" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "كلمة مرور خاطئة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nesprávné heslo"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Falsches Passwort"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Contraseña incorrecta"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mauvais mot de passe"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "סיסמה שגויה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "गलत पासवर्ड"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Password errata"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "間違ったパスワード"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "잘못된 비밀번호"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verkeerd wachtwoord"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Senha incorreta"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Senha incorreta"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Неправильный пароль"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yanlış şifre"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Неправильний пароль"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "密码错误"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "密碼錯誤"
}
}
}
},
"Wrong repeated password" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "عدم تطابق كلمة المرور"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nesprávné opakované heslo"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Passwort stimmt nicht überein"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Repetición de contraseña incorrecta"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mauvais mot de passe répété"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הסיסמאות לא תואמות"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "गलत दोहराया गया पासवर्ड"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Password ripetuta errata"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "再入力されたパスワードが一致していません"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "틀린 암호가 반복되었습니다."
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verkeerd herhaald wachtwoord"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Senha de verificação incorreta"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Palavra-passe de confirmação errada"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Несоответствие паролей"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yanlış tekrarlanan şifre"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Паролі не співпадають"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "重复密码输入不正确"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "確認密碼不符 / 再次輸入的密碼錯誤"
}
}
}
},
"Yes" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "نعم"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ano"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ja"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Si"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Oui"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "כן"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "हाँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Si"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "はい"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "예"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ja"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sim"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sim"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Да"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Evet"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Так"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "是的"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "是"
}
}
}
},
"You cannot move an already encrypted note to an encrypted directory. You must first decrypt the note and repeat the steps." : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "لا يمكنك نقل ملاحظة مشفرة بالفعل إلى دليل مشفر. يجب عليك أولاً فك تشفير الملاحظة وتكرار الخطوات."
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Již zašifrovanou poznámku nelze přesunout do zašifrovaného adresáře. Nejprve poznámku dešifrujte a pak to zkuste znovu."
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sie können eine bereits verschlüsselte Notiz nicht in ein verschlüsseltes Verzeichnis verschieben. Sie müssen die Notiz zuerst entschlüsseln und die Schritte wiederholen."
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "No puedes mover una nota ya encriptada a un directorio encriptado. Primero debes desencriptar la nota y repetir los pasos."
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vous ne pouvez pas déplacer une note déjà chiffré vers un répertoire chiffré. Vous devez d'abord déchiffrer la note et répéter les étapes."
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "לא ניתן להעביר פתק שכבר מוצפן לספרייה מוצפנת. תחילה עליך לפענח את הפתק ולחזור על השלבים."
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "आप पहले से एन्क्रिप्टेड नोट को एन्क्रिप्टेड डायरेक्टरी में नहीं ले जा सकते। आपको पहले नोट को डिक्रिप्ट करना होगा और चरणों को दोहराना होगा"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Non è possibile spostare una nota già crittografata in una directory crittografata. È necessario prima decifrare la nota e ripetere i passaggi."
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "すでに暗号化されたノートを暗号化されたディレクトリに移動することはできません。まずノートの暗号化を解除し、手順を繰り返す必要があります。"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "이미 암호화된 노트는 암호화된 디렉토리로 옮길 수 없습니다. 먼저 노트의 암호를 해독하고 단계를 반복하셔야 합니다."
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Je kunt een reeds gecodeerde notitie niet verplaatsen naar een gecodeerde map. Je moet de notitie eerst decoderen en de stappen herhalen."
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Não é possível mover uma nota já criptografada para um diretório criptografado. Você deve primeiro descriptografar a nota e repetir as etapas."
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Não é possível mover uma nota já encriptada para um diretório encriptado. Deve primeiro desencriptar a nota e repetir os passos."
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Нельзя переместить уже зашифрованную заметку в зашифрованный каталог. Необходимо сначала расшифровать заметку и повторить действия."
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zaten şifrelenmiş bir notu şifrelenmiş bir dizine taşıyamazsınız. Önce notu şifresini çözmeli ve adımları tekrarlamalısınız."
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ви не можете перемістити вже зашифровану нотатку до зашифрованого каталогу. Ви повинні спочатку розшифрувати нотатку і повторити кроки."
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "无法将已加密的备忘移动到加密目录。您必须首先解密备忘,然后重复上述步骤。"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "您無法將已加密的筆記移動至已加密的資料夾。請先將該筆記解密,然後再試一次。"
}
}
}
}
},
"version" : "1.0"
}
================================================
FILE: FSNotes/MainWindow.swift
================================================
//
// MainWindow.swift
// FSNotes
//
// Created by Oleksandr Glushchenko on 11/2/17.
// Copyright © 2017 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
class MainWindow: NSWindow {
override func awakeFromNib() {
super.awakeFromNib()
guard UserDefaults.standard.object(forKey: "NSWindow Frame myMainWindow") == nil else { return }
if let screenHeight = NSScreen.main?.frame.height, let screenWidth = NSScreen.main?.frame.width {
let frame = self.frame
let x = (screenWidth - frame.width) / 2
let rect = NSRect(x: x, y: frame.origin.y, width: frame.width, height: screenHeight)
self.setFrame(rect, display: true)
}
}
}
================================================
FILE: FSNotes/MainWindowController.swift
================================================
//
// MainWindowController.swift
// FSNotes
//
// Created by BUDDAx2 on 8/9/17.
// Copyright © 2017 Oleksandr Glushchenko. All rights reserved.
//
import AppKit
class MainWindowController: NSWindowController, NSWindowDelegate {
let notesListUndoManager = UndoManager()
public var lastWindowSize: NSRect? = nil
override func windowDidLoad() {
AppDelegate.mainWindowController = self
self.window?.hidesOnDeactivate = UserDefaultsManagement.hideOnDeactivate
self.window?.titleVisibility = .hidden
self.window?.titlebarAppearsTransparent = true
self.windowFrameAutosaveName = "myMainWindow"
}
func windowDidResize(_ notification: Notification) {
refreshEditArea()
}
func makeNew() {
window?.makeKeyAndOrderFront(self)
NSApp.activate(ignoringOtherApps: true)
refreshEditArea(focusSearch: true)
}
func refreshEditArea(focusSearch: Bool = false) {
guard let vc = ViewController.shared() else { return }
if vc.sidebarOutlineView.isFirstLaunch || focusSearch {
vc.search.window?.makeFirstResponder(vc.search)
} else {
vc.focusEditArea()
}
vc.editor.updateTextContainerInset()
}
func windowWillReturnUndoManager(_ window: NSWindow) -> UndoManager? {
guard let fr = window.firstResponder else {
return notesListUndoManager
}
if fr.isKind(of: NotesTableView.self) {
return notesListUndoManager
}
if fr.isKind(of: EditTextView.self) {
guard let vc = ViewController.shared(), let ev = vc.editor, ev.isEditable else { return notesListUndoManager }
return vc.editorUndoManager
}
return notesListUndoManager
}
public static func shared() -> NSWindow? {
return AppDelegate.mainWindowController?.window
}
func windowDidEnterFullScreen(_ notification: Notification) {
UserDefaultsManagement.fullScreen = true
}
func windowDidExitFullScreen(_ notification: Notification) {
UserDefaultsManagement.fullScreen = false
}
}
================================================
FILE: FSNotes/Model/StorageEntity+CoreDataClass.swift
================================================
//
// StorageEntity+CoreDataClass.swift
//
//
// Created by Oleksandr Glushchenko on 11/14/17.
//
// This file was automatically generated and should not be edited.
//
import Foundation
import CoreData
@objc(StorageEntity)
public class StorageEntity: NSManagedObject {
}
================================================
FILE: FSNotes/Model/StorageEntity+CoreDataProperties.swift
================================================
//
// StorageEntity+CoreDataProperties.swift
//
//
// Created by Oleksandr Glushchenko on 11/14/17.
//
// This file was automatically generated and should not be edited.
//
import Foundation
import CoreData
extension StorageEntity {
@nonobjc public class func fetchRequest() -> NSFetchRequest {
return NSFetchRequest(entityName: "StorageEntity")
}
@NSManaged public var name: String?
@NSManaged public var path: String?
}
================================================
FILE: FSNotes/NSWindowController+.swift
================================================
//
// NSWindowController+.swift
// FSNotes
//
// Created by Oleksandr Hlushchenko on 22.10.2022.
// Copyright © 2022 Oleksandr Hlushchenko. All rights reserved.
//
import Cocoa
extension NSWindowController {
public static var lastWindowSize: NSRect? = nil
public func maximizeWindow() {
let currentSize = window?.frame
if let screen = NSScreen.main {
let size = NSWindowController.lastWindowSize ?? screen.visibleFrame
window?.setFrame(size, display: true, animate: true)
if NSWindowController.lastWindowSize == nil {
NSWindowController.lastWindowSize = currentSize
} else {
NSWindowController.lastWindowSize = nil
}
}
}
}
================================================
FILE: FSNotes/NoteViewController.swift
================================================
//
// NoteViewController.swift
// FSNotes
//
// Created by Oleksandr Hlushchenko on 25.06.2022.
// Copyright © 2022 Oleksandr Hlushchenko. All rights reserved.
//
import Foundation
import AppKit
class NoteViewController: EditorViewController, NSWindowDelegate {
@IBOutlet weak var shareButton: NSButton!
@IBOutlet weak var previewButton: NSButton!
@IBOutlet weak var lockUnlockButton: NSButton!
@IBOutlet weak var titleLabel: TitleTextField!
@IBOutlet weak var editor: EditTextView!
@IBOutlet weak var editorScrollView: EditorScrollView!
@IBOutlet weak var titleBarView: TitleBarView!
@IBOutlet weak var nonSelectedLabel: NSTextField!
public func initWindow() {
view.window?.title = "New note"
view.window?.titleVisibility = .hidden
view.window?.titlebarAppearsTransparent = true
view.window?.backgroundColor = NSColor(named: "background_win")
view.window?.delegate = self
view.window?.setFrameOriginToPositionWindowInCenterOfScreen()
editor.initTextStorage()
editor.editorViewController = self
editor.configure()
vcEditor = editor
vcTitleLabel = titleLabel
vcNonSelectedLabel = nonSelectedLabel
vcEditorScrollView = editorScrollView
editor.updateTextContainerInset()
super.initView()
}
func windowDidResize(_ notification: Notification) {
editor.updateTextContainerInset()
super.viewDidResize()
}
func windowWillClose(_ notification: Notification) {
AppDelegate.noteWindows.removeAll(where: { ($0.contentViewController as? NoteViewController)?.editor.note === editor.note })
}
func windowWillReturnUndoManager(_ window: NSWindow) -> UndoManager? {
if let fr = window.firstResponder,
fr.isKind(of: EditTextView.self),
editor.isEditable {
return editor.editorViewController?.editorUndoManager
}
return nil
}
}
================================================
FILE: FSNotes/Preferences/MasterPasswordViewController.swift
================================================
//
// MasterPasswordViewController.swift
// FSNotes
//
// Created by Oleksandr Glushchenko on 3/20/19.
// Copyright © 2019 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
class MasterPasswordViewController: NSViewController {
override func viewDidAppear() {
hint.stringValue = UserDefaultsManagement.masterPasswordHint
}
@IBOutlet weak var hint: NSTextField!
@IBOutlet weak var currentPassword: NSSecureTextField!
@IBOutlet weak var newPassword: NSSecureTextField!
@IBOutlet weak var repeatedPassword: NSSecureTextField!
@IBAction func close(_ sender: Any) {
dismiss(self)
}
@IBAction func change(_ sender: Any) {
var password = String()
do {
let item = KeychainPasswordItem(service: KeychainConfiguration.serviceName, account: "Master Password")
password = try item.readPassword()
} catch {
print(error)
}
if password.count > 0, currentPassword.stringValue != password {
wrongCurrentPassword()
return
}
if newPassword.stringValue != repeatedPassword.stringValue {
wrongRepeatAlert()
return
}
if newPassword.stringValue.count == 0 {
emptyPassword()
return
}
let item = KeychainPasswordItem(service: KeychainConfiguration.serviceName, account: "Master Password")
do {
try item.savePassword(newPassword.stringValue)
} catch {
print("Master password saving error: \(error)")
}
UserDefaultsManagement.masterPasswordHint = hint.stringValue
dismiss(self)
}
private func wrongRepeatAlert() {
let alert = NSAlert()
alert.alertStyle = .critical
alert.informativeText = NSLocalizedString("Please try again", comment: "")
alert.messageText = NSLocalizedString("Wrong repeated password", comment: "")
alert.runModal()
}
private func wrongCurrentPassword() {
let alert = NSAlert()
alert.alertStyle = .critical
alert.informativeText = NSLocalizedString("Please try again", comment: "")
alert.messageText = NSLocalizedString("Current password does not match with password in keychain", comment: "")
alert.runModal()
}
private func emptyPassword() {
let alert = NSAlert()
alert.alertStyle = .critical
alert.informativeText = NSLocalizedString("Please try again", comment: "")
alert.messageText = NSLocalizedString("Empty password", comment: "")
alert.runModal()
}
}
================================================
FILE: FSNotes/Preferences/PreferencesAdvancedViewController.swift
================================================
//
// PreferencesAdvancedViewController.swift
// FSNotes
//
// Created by Oleksandr Glushchenko on 3/17/19.
// Copyright © 2019 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
class PreferencesAdvancedViewController: NSViewController {
override func viewWillAppear() {
super.viewWillAppear()
}
@IBOutlet weak var languagePopUp: NSPopUpButton!
@IBOutlet weak var version: NSTextField!
@IBOutlet weak var appearance: NSPopUpButton!
@IBOutlet weak var appearanceLabel: NSTextField!
@IBOutlet weak var dockIconFirst: NSButton!
@IBOutlet weak var dockIconSecond: NSButton!
@IBOutlet weak var trashPath: NSPathControl!
@IBAction func appearanceClick(_ sender: NSPopUpButton) {
if let type = AppearanceType(rawValue: sender.indexOfSelectedItem) {
UserDefaultsManagement.appearanceType = type
}
restart()
}
override func viewDidAppear() {
let languages = [
LanguageType(rawValue: 0),
LanguageType(rawValue: 1),
LanguageType(rawValue: 2),
LanguageType(rawValue: 5),
LanguageType(rawValue: 6),
LanguageType(rawValue: 18),
LanguageType(rawValue: 15),
LanguageType(rawValue: 3),
LanguageType(rawValue: 9),
LanguageType(rawValue: 8),
LanguageType(rawValue: 12),
LanguageType(rawValue: 16),
LanguageType(rawValue: 11),
LanguageType(rawValue: 13),
LanguageType(rawValue: 7),
LanguageType(rawValue: 10),
LanguageType(rawValue: 14),
LanguageType(rawValue: 4),
LanguageType(rawValue: 17)
]
for language in languages {
if let lang = language?.description, let id = language?.rawValue {
languagePopUp.addItem(withTitle: lang)
languagePopUp.lastItem?.state = (id == UserDefaultsManagement.defaultLanguage) ? .on : .off
if id == UserDefaultsManagement.defaultLanguage {
languagePopUp.selectItem(withTitle: lang)
}
}
}
if #available(OSX 10.14, *) {
appearance.selectItem(at: UserDefaultsManagement.appearanceType.rawValue)
} else {
appearanceLabel.isHidden = true
appearance.isHidden = true
}
if let dictionary = Bundle.main.infoDictionary,
let ver = dictionary["CFBundleShortVersionString"] as? String,
let build = dictionary["CFBundleVersion"] as? String {
version.stringValue = "v\(ver) build \(build)"
}
switch UserDefaultsManagement.dockIcon {
case 0:
dockIconFirst.state = .on
break
case 1:
dockIconSecond.state = .on
break
default:
dockIconFirst.state = .on
}
if let url = Storage.shared().getDefaultTrash()?.url {
trashPath.url = url
}
}
@IBAction func languagePopUp(_ sender: NSPopUpButton) {
let type = LanguageType.withName(rawValue: sender.title)
UserDefaultsManagement.defaultLanguage = type.rawValue
UserDefaults.standard.set([type.code], forKey: "AppleLanguages")
UserDefaults.standard.synchronize()
restart()
}
private func restart() {
let url = URL(fileURLWithPath: Bundle.main.resourcePath!)
let path = url.deletingLastPathComponent().deletingLastPathComponent().absoluteString
let task = Process()
task.launchPath = "/usr/bin/open"
task.arguments = [path]
task.launch()
exit(0)
}
@IBAction func dockIcon(_ sender: NSButton) {
UserDefaultsManagement.dockIcon = sender.tag
guard let appDelegate = NSApplication.shared.delegate as? AppDelegate else { return }
appDelegate.loadDockIcon()
}
@IBAction func trash(_ sender: NSButton) {
let openPanel = NSOpenPanel()
openPanel.directoryURL = Storage.shared().getDefaultTrash()?.url
openPanel.allowsMultipleSelection = false
openPanel.canChooseDirectories = true
openPanel.canCreateDirectories = true
openPanel.canChooseFiles = false
openPanel.canSelectHiddenExtension = true
openPanel.begin { (result) -> Void in
if result == .OK {
guard let url = openPanel.url else { return }
let bookmarksManager = SandboxBookmark.sharedInstance()
if let currentURL = UserDefaultsManagement.trashURL {
bookmarksManager.remove(url: currentURL)
}
bookmarksManager.store(url: url)
bookmarksManager.save()
UserDefaultsManagement.trashURL = url
self.trashPath.url = url
Storage.shared().getDefaultTrash()?.url = url
self.restart()
}
}
}
@IBAction func resetCaches(_ sender: Any) {
if let sidebarTreeURL = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first?.appendingPathComponent("sidebarTree") {
try? FileManager.default.removeItem(at: sidebarTreeURL)
}
let projects = Storage.shared().getProjects()
for project in projects {
if let cacheUrl = project.getCacheURL() {
try? FileManager.default.removeItem(at: cacheUrl)
}
project.isReadyForCacheSaving = false
}
restart()
}
@IBAction func resetSettings(_ sender: Any) {
let store = NSUbiquitousKeyValueStore.default
for (key, _) in store.dictionaryRepresentation {
store.removeObject(forKey: key)
}
store.synchronize()
if let bundleID = Bundle.main.bundleIdentifier {
UserDefaults.standard.removePersistentDomain(forName: bundleID)
UserDefaults.standard.synchronize()
}
if let userDefaultsURL = FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask).first?.appendingPathComponent("Preferences").appendingPathComponent("co.fluder.FSNotes.plist") {
try? FileManager.default.removeItem(at: userDefaultsURL)
}
if let editorsURL = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first?.appendingPathComponent("editors.settings") {
try? FileManager.default.removeItem(at: editorsURL)
}
if let notesURL = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first?.appendingPathComponent("notes.settings") {
try? FileManager.default.removeItem(at: notesURL)
}
if let bookmarkUrls = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first?.appendingPathComponent("Bookmarks.dict") {
try? FileManager.default.removeItem(at: bookmarkUrls)
}
restart()
}
}
================================================
FILE: FSNotes/Preferences/PreferencesEditorViewController.swift
================================================
//
// PreferencesEditorViewController.swift
// FSNotes
//
// Created by Oleksandr Glushchenko on 3/17/19.
// Copyright © 2019 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
class PreferencesEditorViewController: NSViewController {
@IBOutlet weak var codeFontPreview: NSTextField!
@IBOutlet weak var noteFontPreview: NSTextField!
@IBOutlet weak var codeBlockHighlight: NSButton!
@IBOutlet weak var markdownCodeTheme: NSPopUpButton!
@IBOutlet weak var indentUsing: NSPopUpButton!
@IBOutlet weak var inEditorFocus: NSButton!
@IBOutlet weak var autocloseBrackets: NSButton!
@IBOutlet weak var lineSpacing: NSSlider!
@IBOutlet weak var imagesWidth: NSSlider!
@IBOutlet weak var lineWidth: NSSlider!
@IBOutlet weak var marginSize: NSSlider!
@IBOutlet weak var inlineTags: NSButton!
@IBOutlet weak var clickableLinks: NSButton!
@IBOutlet weak var italicAsterisk: NSButton!
@IBOutlet weak var italicUnderscore: NSButton!
@IBOutlet weak var boldAsterisk: NSButton!
@IBOutlet weak var boldUnderscore: NSButton!
override func viewWillAppear() {
super.viewWillAppear()
preferredContentSize = NSSize(width: 550, height: 495)
}
override func viewDidAppear() {
if let window = self.view.window {
window.title = NSLocalizedString("Settings", comment: "")
}
codeBlockHighlight.state = UserDefaultsManagement.codeBlockHighlight ? NSControl.StateValue.on : NSControl.StateValue.off
inEditorFocus.state = UserDefaultsManagement.focusInEditorOnNoteSelect ? NSControl.StateValue.on : NSControl.StateValue.off
indentUsing.selectItem(at: UserDefaultsManagement.indentUsing)
autocloseBrackets.state = UserDefaultsManagement.autocloseBrackets ? .on : .off
markdownCodeTheme.selectItem(withTitle: UserDefaultsManagement.codeTheme.getName())
lineSpacing.floatValue = Float((UserDefaultsManagement.lineHeightMultiple - 1) * 10)
imagesWidth.floatValue = UserDefaultsManagement.imagesWidth
lineWidth.floatValue = UserDefaultsManagement.lineWidth
marginSize.floatValue = UserDefaultsManagement.marginSize
inlineTags.state = UserDefaultsManagement.inlineTags ? .on : .off
clickableLinks.state = UserDefaultsManagement.clickableLinks ? .on : .off
setCodeFontPreview()
setNoteFontPreview()
italicAsterisk.state = UserDefaultsManagement.italic == "*" ? .on : .off
italicUnderscore.state = UserDefaultsManagement.italic == "_" ? .on : .off
boldAsterisk.state = UserDefaultsManagement.bold == "**" ? .on : .off
boldUnderscore.state = UserDefaultsManagement.bold == "__" ? .on : .off
}
//MARK: global variables
let storage = Storage.shared()
@IBAction func codeBlockHighlight(_ sender: NSButton) {
UserDefaultsManagement.codeBlockHighlight = (sender.state == NSControl.StateValue.on)
Storage.shared().resetCacheAttributes()
let editors = AppDelegate.getEditTextViews()
for editor in editors {
if let evc = editor.editorViewController {
evc.refillEditArea(force: true)
}
}
}
@IBAction func markdownCodeThemeAction(_ sender: NSPopUpButton) {
guard let item = sender.selectedItem else {
return
}
Storage.shared().resetCacheAttributes()
if let theme = EditorTheme(themeName: item.title) {
UserDefaultsManagement.codeTheme = theme
}
let editors = AppDelegate.getEditTextViews()
for editor in editors {
if let evc = editor.editorViewController {
editor.textStorage?.updateParagraphStyle()
MPreviewView.template = nil
NotesTextProcessor.resetCaches()
evc.refillEditArea(force: true)
}
}
}
@IBAction func inEditorFocus(_ sender: NSButton) {
UserDefaultsManagement.focusInEditorOnNoteSelect = (sender.state == .on)
}
@IBAction func autocloseBrackets(_ sender: NSButton) {
UserDefaultsManagement.autocloseBrackets = (sender.state == .on)
}
@IBAction func lineSpacing(_ sender: NSSlider) {
UserDefaultsManagement.editorLineSpacing = 1
UserDefaultsManagement.lineHeightMultiple = CGFloat(1 + sender.floatValue / 10)
let editors = AppDelegate.getEditTextViews()
for editor in editors {
if let evc = editor.editorViewController {
MPreviewView.template = nil
NotesTextProcessor.resetCaches()
if let lm = evc.vcEditor?.layoutManager as? LayoutManager {
lm.lineHeightMultiple = CGFloat(UserDefaultsManagement.lineHeightMultiple)
lm.refreshLayoutSoftly()
}
}
}
}
@IBAction func imagesWidth(_ sender: NSSlider) {
UserDefaultsManagement.imagesWidth = sender.floatValue
var temporary = URL(fileURLWithPath: NSTemporaryDirectory())
temporary.appendPathComponent("ThumbnailsBig")
try? FileManager.default.removeItem(at: temporary)
let editors = AppDelegate.getEditTextViews()
for editor in editors {
if let note = editor.note, let evc = editor.editorViewController {
NotesTextProcessor.highlight(attributedString: note.content)
evc.disablePreview()
evc.refillEditArea()
}
}
}
@IBAction func lineWidth(_ sender: NSSlider) {
UserDefaultsManagement.lineWidth = sender.floatValue
let editors = AppDelegate.getEditTextViews()
for editor in editors {
if let evc = editor.editorViewController {
editor.updateTextContainerInset()
MPreviewView.template = nil
NotesTextProcessor.resetCaches()
evc.refillEditArea(force: true)
}
}
}
private func restart() {
let url = URL(fileURLWithPath: Bundle.main.resourcePath!)
let path = url.deletingLastPathComponent().deletingLastPathComponent().absoluteString
let task = Process()
task.launchPath = "/usr/bin/open"
task.arguments = [path]
task.launch()
exit(0)
}
@IBAction func indentUsing(_ sender: NSPopUpButton) {
guard let item = sender.selectedItem else {
return
}
UserDefaultsManagement.indentUsing = item.tag
}
@IBAction func marginSize(_ sender: NSSlider) {
UserDefaultsManagement.marginSize = sender.floatValue
let editors = AppDelegate.getEditTextViews()
for editor in editors {
if let evc = editor.editorViewController {
editor.updateTextContainerInset()
MPreviewView.template = nil
NotesTextProcessor.resetCaches()
evc.refillEditArea(force: true)
}
}
}
@IBAction func inlineTags(_ sender: NSButton) {
UserDefaultsManagement.inlineTags = (sender.state == .on)
guard let vc = ViewController.shared() else { return }
Storage.shared().tags = []
for note in Storage.shared().noteList {
note.tags = []
if UserDefaultsManagement.inlineTags {
_ = note.scanContentTags()
}
}
vc.sidebarOutlineView.reloadSidebar()
}
@IBAction func highlightLinks(_ sender: NSButton) {
UserDefaultsManagement.clickableLinks = (sender.state == NSControl.StateValue.on)
Storage.shared().resetCacheAttributes()
let editors = AppDelegate.getEditTextViews()
for editor in editors {
if let evc = editor.editorViewController {
evc.refillEditArea()
}
}
}
@IBAction func setCodeFont(_ sender: NSButton) {
let fontManager = NSFontManager.shared
fontManager.setSelectedFont(UserDefaultsManagement.codeFont, isMultiple: false)
fontManager.orderFrontFontPanel(self)
fontManager.target = self
fontManager.action = #selector(changeCodeFont(_:))
}
@IBAction func setNoteFont(_ sender: NSButton) {
let fontManager = NSFontManager.shared
fontManager.setSelectedFont(UserDefaultsManagement.noteFont, isMultiple: false)
fontManager.orderFrontFontPanel(self)
fontManager.target = self
fontManager.action = #selector(changeNoteFont(_:))
}
@IBAction func changeCodeFont(_ sender: Any?) {
let fontManager = NSFontManager.shared
let newFont = fontManager.convert(UserDefaultsManagement.codeFont)
UserDefaultsManagement.codeFont = newFont
NotesTextProcessor.codeFont = newFont
ViewController.shared()?.reloadFonts()
setCodeFontPreview()
}
@IBAction func changeNoteFont(_ sender: Any?) {
let fontManager = NSFontManager.shared
let newFont = fontManager.convert(UserDefaultsManagement.noteFont)
UserDefaultsManagement.noteFont = newFont
ViewController.shared()?.reloadFonts()
setNoteFontPreview()
}
@IBAction func resetFont(_ sender: Any) {
UserDefaultsManagement.fontName = nil
UserDefaultsManagement.codeFontName = "Source Code Pro"
ViewController.shared()?.reloadFonts()
setCodeFontPreview()
setNoteFontPreview()
}
@IBAction func changeItalic(_ sender: NSButton) {
UserDefaultsManagement.italic = sender.identifier?.rawValue == "italicAsterisk" ? "*" : "_"
italicAsterisk.state = sender.identifier?.rawValue == "italicAsterisk" ? .on : .off
italicUnderscore.state = sender.identifier?.rawValue == "italicUnderscore" ? .on : .off
}
@IBAction func changeBold(_ sender: NSButton) {
UserDefaultsManagement.bold = sender.identifier?.rawValue == "boldAsterisk" ? "**" : "__"
boldAsterisk.state = sender.identifier?.rawValue == "boldAsterisk" ? .on : .off
boldUnderscore.state = sender.identifier?.rawValue == "boldUnderscore" ? .on : .off
}
private func setCodeFontPreview() {
let familyName = UserDefaultsManagement.codeFont.familyName ?? "Source Code Pro"
codeFontPreview.font = NSFont(name: familyName, size: 13)
codeFontPreview.stringValue = "\(familyName) \(UserDefaultsManagement.codeFont.pointSize)pt"
}
private func setNoteFontPreview() {
noteFontPreview.font = NSFont(name: UserDefaultsManagement.noteFont.fontName, size: 13)
if let familyName = UserDefaultsManagement.noteFont.familyName {
noteFontPreview.stringValue = "\(familyName) \(UserDefaultsManagement.noteFont.pointSize)pt"
}
}
}
================================================
FILE: FSNotes/Preferences/PreferencesGeneralViewController.swift
================================================
//
// PreferencesGeneralViewController.swift
// FSNotes
//
// Created by Oleksandr Glushchenko on 3/17/19.
// Copyright © 2019 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
import MASShortcut
import CoreData
class PreferencesGeneralViewController: NSViewController, NSTextFieldDelegate {
override func viewWillAppear() {
super.viewWillAppear()
preferredContentSize = NSSize(width: 550, height: 481)
}
@IBOutlet var externalEditorApp: NSTextField!
@IBOutlet var newNoteshortcutView: MASShortcutView!
@IBOutlet var searchNotesShortcut: MASShortcutView!
@IBOutlet var activateShortcut: MASShortcutView!
@IBOutlet weak var quickNote: MASShortcutView!
@IBOutlet weak var defaultStoragePath: NSPathControl!
@IBOutlet weak var searchFocusOnESC: NSButton!
@IBOutlet weak var defaultExtension: NSPopUpButton!
@IBOutlet weak var fileContainer: NSPopUpButton!
@IBOutlet weak var filesNaming: NSPopUpButton!
@IBOutlet weak var automaticConflictsResolution: NSButton!
@IBOutlet weak var saveTextBundleMetaData: NSButton!
@IBOutlet weak var textMatchAutoSelection: NSButton!
@IBOutlet weak var hideOnDeactivate: NSButton!
//MARK: global variables
let storage = Storage.shared()
override func viewDidLoad() {
super.viewDidLoad()
initShortcuts()
}
override func viewDidAppear() {
self.view.window!.title = NSLocalizedString("Settings", comment: "")
externalEditorApp.stringValue = UserDefaultsManagement.externalEditor
if let url = UserDefaultsManagement.storageUrl {
defaultStoragePath.url = url
}
searchFocusOnESC.state = UserDefaultsManagement.shouldFocusSearchOnESCKeyDown ? .on : .off
fileContainer.selectItem(withTag: UserDefaultsManagement.fileContainer.tag)
filesNaming.selectItem(withTag: UserDefaultsManagement.naming.tag)
let ext = UserDefaultsManagement.noteExtension
defaultExtension.selectItem(withTitle: "." + ext)
automaticConflictsResolution.state = UserDefaultsManagement.automaticConflictsResolution ? .on : .off
saveTextBundleMetaData.state = UserDefaultsManagement.useTextBundleMetaToStoreDates ? .on : .off
externalEditorApp.delegate = self
textMatchAutoSelection.state = UserDefaultsManagement.textMatchAutoSelection ? .on : .off
hideOnDeactivate.state = UserDefaultsManagement.hideOnDeactivate ? .on : .off
}
@IBAction func textMatchAutoSelection(_ sender: NSButton) {
UserDefaultsManagement.textMatchAutoSelection = (sender.state == .on)
}
@IBAction func changeDefaultStorage(_ sender: Any) {
let openPanel = NSOpenPanel()
openPanel.directoryURL = UserDefaultsManagement.storageUrl
openPanel.canChooseDirectories = true
openPanel.canCreateDirectories = true
openPanel.canChooseFiles = false
openPanel.begin { (result) -> Void in
if result == .OK {
guard let url = openPanel.url else { return }
guard let currentURL = UserDefaultsManagement.storageUrl else { return }
let bookmarksManager = SandboxBookmark.sharedInstance()
bookmarksManager.remove(url: currentURL)
bookmarksManager.store(url: url)
bookmarksManager.save()
UserDefaultsManagement.storageType = .custom
UserDefaultsManagement.customStoragePath = url.path
self.defaultStoragePath.stringValue = url.path
if let appDelegate = NSApplication.shared.delegate as? AppDelegate {
let message = NSLocalizedString("Do you want to move current notes in the new destination?", comment: "");
appDelegate.promptToMoveDatabase(from: currentURL, to: url, messageText: message)
}
self.restart()
}
}
}
@IBAction func externalEditor(_ sender: Any) {
UserDefaultsManagement.externalEditor = externalEditorApp.stringValue
}
@IBAction func searchFocusOnESC(_ sender: NSButton) {
UserDefaultsManagement.shouldFocusSearchOnESCKeyDown = sender.state == .on
}
@IBAction func fileContainer(_ sender: NSPopUpButton) {
guard let item = sender.selectedItem else { return }
if let container = NoteContainer(rawValue: item.tag) {
UserDefaultsManagement.fileContainer = container
}
}
@IBAction func defaultExtension(_ sender: NSPopUpButton) {
let ext = sender.title.replacingOccurrences(of: ".", with: "")
UserDefaultsManagement.noteExtension = ext
UserDefaultsManagement.fileFormat = .Markdown
}
@IBAction func filesNaming(_ sender: NSPopUpButton) {
guard let item = sender.selectedItem else { return }
if let naming = SettingsFilesNaming(rawValue: item.tag) {
UserDefaultsManagement.naming = naming
}
}
@IBAction func automaticConflictsResolution(_ sender: NSButton) {
UserDefaultsManagement.automaticConflictsResolution = sender.state == .on
}
@IBAction func saveTextBundleMetaData(_ sender: NSButton) {
UserDefaultsManagement.useTextBundleMetaToStoreDates = sender.state == .on
}
@IBAction func changeHideOnDeactivate(_ sender: NSButton) {
UserDefaultsManagement.hideOnDeactivate = sender.state == .on
// We don't need to set the user defaults value here as the checkbox is
// bound to it. We do need to update each window's hideOnDeactivate.
for window in NSApplication.shared.windows {
if window.className == "NSStatusBarWindow" {
continue
}
window.hidesOnDeactivate = UserDefaultsManagement.hideOnDeactivate
}
}
func restart() {
let url = URL(fileURLWithPath: Bundle.main.resourcePath!)
let path = url.deletingLastPathComponent().deletingLastPathComponent().absoluteString
let task = Process()
task.launchPath = "/usr/bin/open"
task.arguments = [path]
task.launch()
exit(0)
}
func initShortcuts() {
guard let vc = ViewController.shared() else { return }
let mas = MASShortcutMonitor.shared()
newNoteshortcutView.shortcutValue = UserDefaultsManagement.newNoteShortcut
searchNotesShortcut.shortcutValue = UserDefaultsManagement.searchNoteShortcut
quickNote.shortcutValue = UserDefaultsManagement.quickNoteShortcut
activateShortcut.shortcutValue = UserDefaultsManagement.activateShortcut
newNoteshortcutView.shortcutValidator.allowAnyShortcutWithOptionModifier = true
searchNotesShortcut.shortcutValidator.allowAnyShortcutWithOptionModifier = true
quickNote.shortcutValidator.allowAnyShortcutWithOptionModifier = true
activateShortcut.shortcutValidator.allowAnyShortcutWithOptionModifier = true
newNoteshortcutView.shortcutValueChange = { (sender) in
if ((self.newNoteshortcutView.shortcutValue) != nil) {
mas?.unregisterShortcut(UserDefaultsManagement.newNoteShortcut)
let keyCode = self.newNoteshortcutView.shortcutValue.keyCode
let modifierFlags = self.newNoteshortcutView.shortcutValue.modifierFlags
UserDefaultsManagement.newNoteShortcut = MASShortcut(keyCode: keyCode, modifierFlags: modifierFlags)
MASShortcutMonitor.shared().register(self.newNoteshortcutView.shortcutValue, withAction: {
vc.makeNoteShortcut()
})
} else {
mas?.unregisterShortcut(UserDefaultsManagement.newNoteShortcut)
UserDefaultsManagement.newNoteShortcut = nil
}
}
searchNotesShortcut.shortcutValueChange = { (sender) in
if ((self.searchNotesShortcut.shortcutValue) != nil) {
mas?.unregisterShortcut(UserDefaultsManagement.searchNoteShortcut)
let keyCode = self.searchNotesShortcut.shortcutValue.keyCode
let modifierFlags = self.searchNotesShortcut.shortcutValue.modifierFlags
UserDefaultsManagement.searchNoteShortcut = MASShortcut(keyCode: keyCode, modifierFlags: modifierFlags)
MASShortcutMonitor.shared().register(self.searchNotesShortcut.shortcutValue, withAction: {
vc.searchShortcut()
})
} else {
mas?.unregisterShortcut(UserDefaultsManagement.searchNoteShortcut)
UserDefaultsManagement.searchNoteShortcut = nil
}
}
quickNote.shortcutValueChange = { (sender) in
mas?.unregisterShortcut(UserDefaultsManagement.quickNoteShortcut)
if ((self.quickNote.shortcutValue) != nil) {
let keyCode = self.quickNote.shortcutValue.keyCode
let modifierFlags = self.quickNote.shortcutValue.modifierFlags
UserDefaultsManagement.quickNoteShortcut = MASShortcut(keyCode: keyCode, modifierFlags: modifierFlags)
MASShortcutMonitor.shared().register(self.quickNote.shortcutValue, withAction: {
vc.quickNote(self)
})
} else {
UserDefaultsManagement.quickNoteShortcut = nil
}
}
activateShortcut.shortcutValueChange = { (sender) in
mas?.unregisterShortcut(UserDefaultsManagement.activateShortcut)
if ((self.activateShortcut.shortcutValue) != nil) {
let keyCode = self.activateShortcut.shortcutValue.keyCode
let modifierFlags = self.activateShortcut.shortcutValue.modifierFlags
UserDefaultsManagement.activateShortcut = MASShortcut(keyCode: keyCode, modifierFlags: modifierFlags)
MASShortcutMonitor.shared().register(self.activateShortcut.shortcutValue, withAction: {
vc.searchShortcut(activate: true)
})
} else {
UserDefaultsManagement.activateShortcut = nil
}
}
}
func controlTextDidChange(_ notification: Notification) {
guard let textField = notification.object as? NSTextField else { return }
if textField.identifier?.rawValue == "openInExternalEditor" {
UserDefaultsManagement.externalEditor = externalEditorApp.stringValue
}
}
}
================================================
FILE: FSNotes/Preferences/PreferencesGitViewController.swift
================================================
//
// PreferencesGitViewController.swift
// FSNotes
//
// Created by Олександр Глущенко on 9/8/19.
// Copyright © 2019 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
class PreferencesGitViewController: SettingsViewController {
@IBOutlet weak var repositoriesPath: NSPathControl!
@IBOutlet weak var snapshotsTextField: NSTextField!
@IBOutlet weak var minutes: NSTextField!
@IBOutlet weak var backupManually: NSButton!
@IBOutlet weak var backupBySchedule: NSButton!
@IBOutlet weak var pullInterval: NSTextField!
@IBOutlet weak var separateDotGit: NSButton!
@IBOutlet weak var askCommitMessage: NSButton!
override func viewWillAppear() {
super.viewWillAppear()
//preferredContentSize = NSSize(width: 460, height: 579)
loadGit(project: Storage.shared().getDefault()!)
repositoriesPath.url = UserDefaultsManagement.gitStorage
snapshotsTextField.stringValue = String(UserDefaultsManagement.snapshotsInterval)
minutes.stringValue = String(UserDefaultsManagement.snapshotsIntervalMinutes)
backupManually.state = UserDefaultsManagement.backupManually ? .on : .off
backupBySchedule.state = UserDefaultsManagement.backupManually ? .off : .on
pullInterval.stringValue = String(UserDefaultsManagement.pullInterval)
separateDotGit.state = UserDefaultsManagement.separateRepo ? .on : .off
askCommitMessage.state = UserDefaultsManagement.askCommitMessage ? .on : .off
}
@IBAction func changeGitStorage(_ sender: NSButton) {
let openPanel = NSOpenPanel()
openPanel.directoryURL = UserDefaultsManagement.gitStorage
openPanel.allowsMultipleSelection = false
openPanel.canChooseDirectories = true
openPanel.canCreateDirectories = true
openPanel.canChooseFiles = false
openPanel.begin { (result) -> Void in
if result == .OK {
guard let url = openPanel.url?.standardized,
url != UserDefaultsManagement.storageUrl else {
let alert = NSAlert()
alert.alertStyle = .critical
alert.informativeText = NSLocalizedString("Path not available", comment: "")
alert.messageText = NSLocalizedString("Default storage path should not be equal to Git path.", comment: "")
alert.runModal()
return
}
let bookmarksManager = SandboxBookmark.sharedInstance()
if let currentURL = UserDefaultsManagement.gitStorage {
bookmarksManager.remove(url: currentURL)
}
bookmarksManager.store(url: url)
bookmarksManager.save()
UserDefaultsManagement.gitStorage = url
self.repositoriesPath.url = url
}
}
}
@IBAction func showFinder(_ sender: Any) {
guard let storage = UserDefaultsManagement.gitStorage else { return }
NSWorkspace.shared.activateFileViewerSelecting([storage])
}
@IBAction func showTerminal(_ sender: Any) {
guard let storage = UserDefaultsManagement.gitStorage else { return }
NSWorkspace.shared.openFile(storage.path, withApplication: "Terminal.app")
}
@IBAction func backupMethod(_ sender: NSButton) {
guard let ident = sender.identifier?.rawValue else { return }
let isManualBackup = ident == "manual"
UserDefaultsManagement.backupManually = isManualBackup
backupManually.state = isManualBackup ? .on : .off
backupBySchedule.state = isManualBackup ? .off : .on
guard let vc = ViewController.shared() else { return }
if backupBySchedule.state == .on {
vc.schedulePull()
} else {
vc.stopPull()
}
}
@IBAction func changeSnapshotIntervalByHours(_ sender: NSTextField) {
if sender.stringValue == "0" || sender.stringValue.trim() == "" {
sender.stringValue = "1"
}
if let interval = Int(sender.stringValue) {
UserDefaultsManagement.snapshotsInterval = interval
}
guard let vc = ViewController.shared() else { return }
vc.scheduleSnapshots()
}
@IBAction func changeSnapshotsIntervalByMinutes(_ sender: NSTextField) {
if let interval = Int(sender.stringValue) {
UserDefaultsManagement.snapshotsIntervalMinutes = interval
}
guard let vc = ViewController.shared() else { return }
vc.scheduleSnapshots()
}
@IBAction func pullInterval(_ sender: NSTextField) {
if var interval = Int(sender.stringValue) {
if interval < 10 {
interval = 10
pullInterval.stringValue = String(10)
}
UserDefaultsManagement.pullInterval = interval
}
guard let vc = ViewController.shared() else { return }
vc.schedulePull()
}
@IBAction func separateRepo(_ sender: NSButton) {
UserDefaultsManagement.separateRepo = sender.state == .on
}
@IBAction func askCommitMessage(_ sender: NSButton) {
UserDefaultsManagement.askCommitMessage = sender.state == .on
}
}
================================================
FILE: FSNotes/Preferences/PreferencesSecurityViewController.swift
================================================
//
// PreferencesSecurityViewController.swift
// FSNotes
//
// Created by Oleksandr Glushchenko on 3/17/19.
// Copyright © 2019 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
import LocalAuthentication
class PreferencesSecurityViewController: NSViewController {
@IBOutlet weak var lockOnSleep: NSButton!
@IBOutlet weak var lockOnScreenActivated: NSButton!
@IBOutlet weak var lockWhenFastUser: NSButton!
@IBOutlet weak var allowTouchID: NSButton!
@IBOutlet weak var masterPassword: NSButton!
override func viewDidLoad() {
lockOnSleep.state = UserDefaultsManagement.lockOnSleep ? .on : .off
lockOnScreenActivated.state = UserDefaultsManagement.lockOnSleep ? .on : .off
lockWhenFastUser.state = UserDefaultsManagement.lockOnUserSwitch ? .on : .off
allowTouchID.state = UserDefaultsManagement.allowTouchID ? .on : .off
allowTouchID.isEnabled = true
masterPassword.isEnabled = UserDefaultsManagement.allowTouchID
if #available(OSX 10.12.2, *) {
let context = LAContext()
if !context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil) {
disableTouchID()
return
}
} else {
disableTouchID()
}
}
override func viewWillAppear() {
super.viewWillAppear()
preferredContentSize = NSSize(width: 550, height: 352)
}
@IBAction func openMasterPasswordWindow(_ sender: Any) {
guard let vc = ViewController.shared() else { return }
if let controller = vc.storyboard?.instantiateController(withIdentifier: "MasterPasswordViewController") as? MasterPasswordViewController {
presentAsSheet(controller)
}
}
@IBAction func lockOnSleep(_ sender: NSButton) {
UserDefaultsManagement.lockOnSleep = (sender.state == .on)
}
@IBAction func lockOnScreenActivated(_ sender: NSButton) {
UserDefaultsManagement.lockOnScreenActivated = (sender.state == .on)
}
@IBAction func lockWhenSwitched(_ sender: NSButton) {
UserDefaultsManagement.lockOnUserSwitch = (sender.state == .on)
}
@IBAction func allowTouchID(_ sender: NSButton) {
UserDefaultsManagement.allowTouchID = (sender.state == .on)
masterPassword.isEnabled = UserDefaultsManagement.allowTouchID
}
private func disableTouchID() {
masterPassword.isEnabled = false
allowTouchID.isEnabled = false
allowTouchID.state = .off
}
}
================================================
FILE: FSNotes/Preferences/PreferencesUserInterfaceViewController.swift
================================================
//
// PreferencesUserInterfaceViewController.swift
// FSNotes
//
// Created by Oleksandr Glushchenko on 3/17/19.
// Copyright © 2019 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
class PreferencesUserInterfaceViewController: NSViewController {
@IBOutlet weak var cellSpacing: NSSlider!
@IBOutlet weak var previewFontSize: NSPopUpButton!
@IBOutlet weak var hideImagesPreview: NSButton!
@IBOutlet weak var hidePreview: NSButton!
@IBOutlet weak var hideDate: NSButton!
@IBOutlet weak var firstLineAsTitle: NSButton!
@IBOutlet weak var horizontalOrientation: NSButton!
@IBOutlet weak var showDockIcon: NSButton!
@IBOutlet weak var showInMenuBar: NSButton!
override func viewWillAppear() {
super.viewWillAppear()
preferredContentSize = NSSize(width: 550, height: 460)
}
override func viewDidAppear() {
guard let window = self.view.window else { return }
window.title = NSLocalizedString("Settings", comment: "")
hidePreview.state = UserDefaultsManagement.hidePreview ? NSControl.StateValue.on : NSControl.StateValue.off
cellSpacing.doubleValue = Double(UserDefaultsManagement.cellSpacing)
showDockIcon.state = UserDefaultsManagement.showDockIcon ? .on : .off
showInMenuBar.state = UserDefaultsManagement.showInMenuBar ? .on : .off
previewFontSize.selectItem(withTag: UserDefaultsManagement.previewFontSize)
hideImagesPreview.state = UserDefaultsManagement.hidePreviewImages ? .on : .off
hideDate.state = UserDefaultsManagement.hideDate ? .on : .off
firstLineAsTitle.state = UserDefaultsManagement.firstLineAsTitle ? .on : .off
horizontalOrientation.state =
UserDefaultsManagement
.horizontalOrientation ? .on : .off
}
@IBAction func changeCellSpacing(_ sender: NSSlider) {
guard let vc = ViewController.shared() else { return }
vc.setTableRowHeight()
}
@IBAction func changePreview(_ sender: Any) {
guard let vc = ViewController.shared() else { return }
UserDefaultsManagement.hidePreview = ((sender as AnyObject).state == NSControl.StateValue.on)
vc.notesTableView.reloadData()
}
@IBAction func hideImagesPreview(_ sender: NSButton) {
UserDefaultsManagement.hidePreviewImages = sender.state == .on
guard let vc = ViewController.shared() else { return }
vc.notesTableView.reloadData()
}
@IBAction func changePreviewFontSize(_ sender: NSPopUpButton) {
guard let tag = sender.selectedItem?.tag else { return }
UserDefaultsManagement.previewFontSize = tag
guard let vc = ViewController.shared() else { return }
vc.notesTableView.reloadData()
}
@IBAction func hideDate(_ sender: NSButton) {
UserDefaultsManagement.hideDate = (sender.state == .on)
guard let vc = ViewController.shared() else { return }
vc.notesTableView.reloadData()
}
@IBAction func firstLineAsTitle(_ sender: NSButton) {
UserDefaultsManagement.firstLineAsTitle = (sender.state == .on)
let storage = Storage.shared()
for note in storage.noteList {
note.invalidateCache()
}
guard let vc = ViewController.shared() else { return }
vc.notesTableView.reloadData()
}
@IBAction func horizontalOrientation(_ sender: NSButton) {
UserDefaultsManagement.horizontalOrientation = (sender.state == .on)
let task = Process()
task.launchPath = "/usr/bin/open"
task.arguments = [Bundle.main.bundlePath]
try? task.run()
NSApp.terminate(nil)
}
@IBAction func showDockIcon(_ sender: NSButton) {
let isEnabled = sender.state == .on
UserDefaultsManagement.showDockIcon = isEnabled
NSApp.setActivationPolicy(isEnabled ? .regular : .accessory)
DispatchQueue.main.async {
NSMenu.setMenuBarVisible(true)
NSApp.activate(ignoringOtherApps: true)
}
}
@IBAction func showInMenuBar(_ sender: NSButton) {
UserDefaultsManagement.showInMenuBar = sender.state == .on
guard let appDelegate = NSApplication.shared.delegate as? AppDelegate else { return }
if sender.state == .off {
appDelegate.removeMenuBar(nil)
return
}
appDelegate.addMenuBar(nil)
}
}
================================================
FILE: FSNotes/Preferences/PreferencesWebViewController.swift
================================================
//
// PreferencesWebViewController.swift
// FSNotes
//
// Created by Oleksandr Hlushchenko on 20.08.2022.
// Copyright © 2022 Oleksandr Hlushchenko. All rights reserved.
//
import Cocoa
import Shout
class PreferencesWebViewController: NSViewController, NSTextFieldDelegate {
override func viewWillAppear() {
super.viewWillAppear()
preferredContentSize = NSSize(width: 550, height: 512)
host.stringValue = UserDefaultsManagement.sftpHost
port.stringValue = String(UserDefaultsManagement.sftpPort)
path.stringValue = UserDefaultsManagement.sftpPath ?? ""
web.stringValue = UserDefaultsManagement.sftpWeb ?? ""
username.stringValue = UserDefaultsManagement.sftpUsername
password.stringValue = UserDefaultsManagement.sftpPassword
passphrase.stringValue = UserDefaultsManagement.sftpPassphrase
if let accessData = UserDefaultsManagement.sftpAccessData,
let bookmarks = try? NSKeyedUnarchiver.unarchivedObject(ofClasses: [NSDictionary.self, NSURL.self, NSData.self], from: accessData) as? [URL: Data] {
for bookmark in bookmarks {
rsaPath.url = bookmark.key
break
}
}
publishFSNotes.state = UserDefaultsManagement.customWebServer ? .off : .on
publishCustom.state = UserDefaultsManagement.customWebServer ? .on : .off
if !UserDefaultsManagement.customWebServer {
toggleState(state: false)
}
username.delegate = self
port.delegate = self
path.delegate = self
web.delegate = self
username.delegate = self
password.delegate = self
passphrase.delegate = self
}
@IBOutlet weak var host: NSTextField!
@IBOutlet weak var port: NSTextField!
@IBOutlet weak var path: NSTextField!
@IBOutlet weak var web: NSTextField!
@IBOutlet weak var username: NSTextField!
@IBOutlet weak var password: NSSecureTextField!
@IBOutlet weak var rsaPath: NSPathControl!
@IBOutlet weak var key: NSButton!
@IBOutlet weak var passphrase: NSSecureTextField!
@IBOutlet weak var publishFSNotes: NSButton!
@IBOutlet weak var publishCustom: NSButton!
@IBOutlet weak var uploadAndTest: NSButton!
@IBAction func host(_ sender: NSTextField) {
UserDefaultsManagement.sftpHost = sender.stringValue
}
@IBAction func port(_ sender: NSTextField) {
if let port = Int32(sender.stringValue) {
UserDefaultsManagement.sftpPort = port
}
}
@IBAction func path(_ sender: NSTextField) {
UserDefaultsManagement.sftpPath = sender.stringValue
}
@IBAction func web(_ sender: NSTextField) {
UserDefaultsManagement.sftpWeb = sender.stringValue
}
@IBAction func username(_ sender: NSTextField) {
UserDefaultsManagement.sftpUsername = sender.stringValue
}
@IBAction func password(_ sender: NSSecureTextField) {
UserDefaultsManagement.sftpPassword = sender.stringValue
}
@IBAction func passphrase(_ sender: NSSecureTextField) {
UserDefaultsManagement.sftpPassphrase = sender.stringValue
}
@IBAction func privateKey(_ sender: Any) {
let openPanel = NSOpenPanel()
openPanel.allowsMultipleSelection = true
openPanel.canChooseFiles = true
openPanel.begin { (result) -> Void in
if result == .OK {
if openPanel.urls.count != 2 {
let alert = NSAlert()
alert.alertStyle = .warning
alert.informativeText = NSLocalizedString("Please select private and public key", comment: "")
alert.runModal()
return
}
var bookmarks = [URL: Data]()
for url in openPanel.urls {
do {
let data = try url.bookmarkData(options: NSURL.BookmarkCreationOptions.withSecurityScope, includingResourceValuesForKeys: nil, relativeTo: nil)
bookmarks[url] = data
} catch {
print(error.localizedDescription)
}
}
let data = try? NSKeyedArchiver.archivedData(withRootObject: bookmarks, requiringSecureCoding: true)
UserDefaultsManagement.sftpAccessData = data
self.rsaPath.url = openPanel.urls[0]
}
}
}
@IBAction func test(_ sender: Any) {
var publicKeyURL: URL?
var privateKeyURL: URL?
if let accessData = UserDefaultsManagement.sftpAccessData,
let bookmarks = try? NSKeyedUnarchiver.unarchivedObject(ofClasses: [NSDictionary.self, NSURL.self, NSData.self], from: accessData) as? [URL: Data] {
for bookmark in bookmarks {
if bookmark.key.path.hasSuffix(".pub") {
publicKeyURL = bookmark.key
} else {
privateKeyURL = bookmark.key
}
}
}
let host = UserDefaultsManagement.sftpHost
let port = UserDefaultsManagement.sftpPort
let username = UserDefaultsManagement.sftpUsername
let password = UserDefaultsManagement.sftpPassword
let passphrase = UserDefaultsManagement.sftpPassphrase
if password.count == 0, publicKeyURL == nil || publicKeyURL == nil {
uploadError(text: "Please set private and public keys")
return
}
let path = Bundle.main.path(forResource: "MPreview", ofType: ".bundle")
let url = NSURL.fileURL(withPath: path!)
let bundle = Bundle(url: url)
guard let bundleResourceURL = bundle?.resourceURL
else {
uploadError(text: "Test bundle can not found")
return
}
let localJsDir = bundleResourceURL.appendingPathComponent("js", isDirectory: true)
let localFontsDir = bundleResourceURL.appendingPathComponent("fonts", isDirectory: true)
let localCssFile = bundleResourceURL.appendingPathComponent("main.css")
let alert = NSAlert()
do {
let ssh = try SSH(host: host, port: port)
guard let remoteDir = UserDefaultsManagement.sftpPath else { throw "Please enter remote path" }
let remoteJsDir = "\(remoteDir)js/"
let remoteFontsDir = "\(remoteDir)fonts/"
guard let files = try? FileManager.default.contentsOfDirectory(atPath: localJsDir.path) else { return }
guard let fontFiles = try? FileManager.default.contentsOfDirectory(atPath: localFontsDir.path) else { return }
if password.count > 0 {
try ssh.authenticate(username: username, password: password)
} else if let publicKeyURL = publicKeyURL, let privateKeyURL = privateKeyURL {
try ssh.authenticate(username: username, privateKey: privateKeyURL.path, publicKey: publicKeyURL.path, passphrase: passphrase)
}
_ = try ssh.execute("mkdir -p \(remoteJsDir)")
_ = try ssh.execute("mkdir -p \(remoteFontsDir)")
let permissions = Permissions(arrayLiteral: .write, .read, .execute)
let filePerm = FilePermissions(owner: permissions, group: permissions, others: permissions)
let sftp = try ssh.openSftp()
for file in files {
let localURL = localJsDir.appendingPathComponent(file)
try? sftp.upload(localURL: localURL, remotePath: remoteJsDir + file, permissions: filePerm)
}
for file in fontFiles {
let localURL = localFontsDir.appendingPathComponent(file)
try? sftp.upload(localURL: localURL, remotePath: remoteFontsDir + file, permissions: filePerm)
}
try sftp.upload(localURL: localCssFile, remotePath: remoteDir + "main.css", permissions: filePerm)
alert.alertStyle = .informational
alert.messageText = NSLocalizedString("Connection established successfully 🤟", comment: "")
} catch let sshError as SSHError {
alert.alertStyle = .critical
alert.informativeText = sshError.description
alert.messageText = NSLocalizedString("SSH error", comment: "")
} catch {
alert.alertStyle = .critical
alert.informativeText = error.localizedDescription
alert.messageText = NSLocalizedString("SSH error", comment: "")
}
alert.beginSheetModal(for: self.view.window!)
}
private func uploadError(text: String) {
let alert = NSAlert()
alert.alertStyle = .critical
alert.informativeText = NSLocalizedString("Upload error", comment: "")
alert.messageText = text
alert.beginSheetModal(for: self.view.window!)
}
@IBAction func publishTo(_ sender: NSButton) {
if sender.tag == 0 {
publishCustom.state = .off
toggleState(state: false)
} else {
publishFSNotes.state = .off
toggleState(state: true)
}
UserDefaultsManagement.customWebServer = publishCustom.state == .on
}
public func toggleState(state: Bool) {
host.isEnabled = state
port.isEnabled = state
path.isEnabled = state
web.isEnabled = state
username.isEnabled = state
password.isEnabled = state
passphrase.isEnabled = state
uploadAndTest.isEnabled = state
key.isEnabled = state
}
@IBAction func resetWebKeys(_ sender: NSButton) {
UserDefaultsManagement.sftpAccessData = nil
rsaPath.url = nil
}
func controlTextDidChange(_ notification: Notification) {
guard let textField = notification.object as? NSTextField, let value = textField.identifier?.rawValue else { return }
switch value {
case "settingsWebHost":
UserDefaultsManagement.sftpHost = host.stringValue
case "settingsWebPort":
UserDefaultsManagement.sftpPort = Int32(port.stringValue) ?? 22
case "settingsWebPath":
UserDefaultsManagement.sftpPath = path.stringValue
case "settingsWebWeb":
UserDefaultsManagement.sftpWeb = web.stringValue
case "settingsWebUsername":
UserDefaultsManagement.sftpUsername = username.stringValue
case "settingsWebPassword":
UserDefaultsManagement.sftpPassword = password.stringValue
case "settingsWebPassphrase":
UserDefaultsManagement.sftpPassphrase = passphrase.stringValue
default: break
}
}
}
extension String: LocalizedError { // Adds error.localizedDescription to Error instances
public var errorDescription: String? { return self }
}
================================================
FILE: FSNotes/Preferences/SettingsViewController.swift
================================================
//
// SettingsViewController.swift
// FSNotes
//
// Created by Oleksandr Hlushchenko on 14.03.2023.
// Copyright © 2023 Oleksandr Hlushchenko. All rights reserved.
//
import AppKit
class SettingsViewController: NSViewController, NSTextFieldDelegate {
public var gitProject: Project?
public var project: Project?
public var progress: GitProgress?
override func viewDidAppear() {
passphrase.delegate = self
origin.delegate = self
}
@IBOutlet weak var origin: NSTextField!
@IBOutlet weak var keyStatus: NSTextField!
@IBOutlet weak var logTextField: NSTextField!
@IBOutlet weak var removeButton: NSButton!
@IBOutlet weak var cloneButton: NSButton!
@IBOutlet weak var passphrase: NSSecureTextField!
@IBOutlet weak var progressIndicator: NSProgressIndicator!
@IBAction func removeRepository(_ sender: Any) {
gitProject?.removeRepository(progress: progress)
updateButtons()
}
@IBAction func origin(_ sender: Any) {
gitProject?.settings.setOrigin(origin.stringValue)
gitProject?.saveSettings()
updateButtons()
}
@IBAction func passphrase(_ sender: Any) {
gitProject?.settings.gitPrivateKeyPassphrase = passphrase.stringValue
gitProject?.saveSettings()
}
@IBAction func clonePull(_ sender: Any) {
guard let project = self.gitProject else { return }
if let origin = project.settings.gitOrigin, origin.startsWith(string: "https://") {
let alert = NSAlert()
alert.messageText = "Wrong configuration"
alert.alertStyle = .critical
alert.informativeText = "Please use ssh keys, https auth is not supported"
alert.runModal()
return
}
let action = project.getRepositoryState()
updateButtons(isActive: true)
ViewController.gitQueue.addOperation({
defer {
ViewController.gitQueueOperationDate = nil
ViewController.gitQueueBusy = false
DispatchQueue.main.async {
self.updateButtons(isActive: false)
}
}
ViewController.gitQueueOperationDate = Date()
ViewController.gitQueueBusy = true
if let message = project.gitDo(action, progress: self.progress) {
DispatchQueue.main.async {
let alert = NSAlert()
alert.alertStyle = .critical
alert.informativeText = message
alert.messageText = NSLocalizedString("git error", comment: "")
alert.runModal()
}
}
})
}
@IBAction func privateKey(_ sender: Any) {
let openPanel = NSOpenPanel()
openPanel.allowsMultipleSelection = true
openPanel.canChooseFiles = true
openPanel.begin { (result) -> Void in
if result == .OK {
if openPanel.urls.count != 1 {
let alert = NSAlert()
alert.alertStyle = .warning
alert.informativeText = NSLocalizedString("Please select private key", comment: "")
alert.runModal()
return
}
self.gitProject?.settings.gitPrivateKey = try? Data(contentsOf: openPanel.urls[0])
self.gitProject?.saveSettings()
self.keyStatus.stringValue = "✅"
}
}
}
@IBAction func resetKey(_ sender: Any) {
gitProject?.removeSSHKey()
gitProject?.settings.gitPrivateKey = nil
gitProject?.saveSettings()
keyStatus.stringValue = ""
}
public func controlTextDidChange(_ notification: Notification) {
guard let textField = notification.object as? NSTextField else { return }
let id = textField.identifier?.rawValue
if id == "gitOrigin" || id == "gitOriginMain" {
gitProject?.settings.setOrigin(textField.stringValue)
updateButtons()
}
if id == "gitPassphrase" || id == "gitPassphraseMain" {
gitProject?.settings.gitPrivateKeyPassphrase = textField.stringValue
}
DispatchQueue.global(qos: .background).async {
self.gitProject?.saveSettings()
}
}
public func updateButtons(isActive: Bool? = nil) {
guard let project = gitProject else { return }
progressIndicator.isHidden = !project.isActiveGit
cloneButton.title = project.getRepositoryState().title
removeButton.isEnabled = project.hasRepository()
if let isActive = isActive {
if isActive {
progressIndicator.startAnimation(nil)
progressIndicator.isHidden = false
} else {
progressIndicator.stopAnimation(nil)
progressIndicator.isHidden = true
}
}
}
public func loadGit(project: Project) {
var project = project
if project.isVirtual {
if let defaultProject = Storage.shared().getDefault() {
project = defaultProject
}
}
self.gitProject = project
origin.stringValue = project.settings.gitOrigin ?? ""
passphrase.stringValue = project.settings.gitPrivateKeyPassphrase ?? ""
keyStatus.stringValue = project.settings.gitPrivateKey != nil ? "✅" : ""
updateButtons()
progress = GitProgress(statusTextField: logTextField, project: project)
// Global instance for libgit2 callbacks
AppDelegate.gitProgress = progress
if let status = project.gitStatus {
logTextField.stringValue = status
}
}
}
================================================
FILE: FSNotes/PrefsViewController.swift
================================================
//
// PrefsViewController.swift
// FSNotes
//
// Created by Oleksandr Glushchenko on 8/4/17.
// Copyright © 2017 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
import MASShortcut
import CoreData
class PrefsViewController: NSTabViewController {
@IBOutlet weak var generalTabViewItem: NSTabViewItem!
@IBOutlet weak var libraryTabViewItem: NSTabViewItem!
@IBOutlet weak var editorTabViewItem: NSTabViewItem!
@IBOutlet weak var securityTabViewItem: NSTabViewItem!
@IBOutlet weak var gitTabViewItem: NSTabViewItem!
@IBOutlet weak var webTabViewItem: NSTabViewItem!
@IBOutlet weak var advancedTabViewItem: NSTabViewItem!
override func viewDidLoad() {
self.title = NSLocalizedString("Settings", comment: "")
super.viewDidLoad()
if #available(macOS 11.0, *) {
let general = NSImage.init(systemSymbolName: "gearshape", accessibilityDescription: nil)
let library = NSImage.init(systemSymbolName: "sidebar.left", accessibilityDescription: nil)
let editor = NSImage.init(systemSymbolName: "doc.richtext", accessibilityDescription: nil)
let security = NSImage.init(systemSymbolName: "lock", accessibilityDescription: nil)
let git = NSImage.init(systemSymbolName: "arrow.triangle.pull", accessibilityDescription: nil)
let web = NSImage.init(systemSymbolName: "globe", accessibilityDescription: nil)
let advanced = NSImage.init(systemSymbolName: "slider.vertical.3", accessibilityDescription: nil)
if let general = general, let library = library, let editor = editor, let security = security, let git = git, let web = web, let advanced = advanced {
generalTabViewItem.image = general
libraryTabViewItem.image = library
editorTabViewItem.image = editor
securityTabViewItem.image = security
gitTabViewItem.image = git
webTabViewItem.image = web
advancedTabViewItem.image = advanced
}
}
}
override func toolbar(_ toolbar: NSToolbar, itemForItemIdentifier itemIdentifier: NSToolbarItem.Identifier, willBeInsertedIntoToolbar flag: Bool) -> NSToolbarItem? {
let toolbarItem = super.toolbar(toolbar, itemForItemIdentifier: itemIdentifier, willBeInsertedIntoToolbar: flag)
if
let toolbarItem = toolbarItem,
let tabViewItem = tabViewItems.first(where: { ($0.identifier as? String) == itemIdentifier.rawValue })
{
if let name = tabViewItem.identifier as? String, name == "git" {
toolbarItem.label = "\(tabViewItem.label) "
return toolbarItem
}
if let name = tabViewItem.identifier as? String, !["advanced", "security"].contains(name) {
toolbarItem.label = "\(tabViewItem.label) "
}
}
return toolbarItem
}
}
================================================
FILE: FSNotes/PrefsWindowController.swift
================================================
//
// PrefsWindowController.swift
// FSNotes
//
// Created by Jeff Hanbury on 13/08/17.
// Copyright © 2017 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
class PrefsWindowController: NSWindowController, NSWindowDelegate {
override func windowDidLoad() {
super.windowDidLoad()
self.window?.delegate = self
self.window?.title = NSLocalizedString("Settings", comment: "")
}
}
================================================
FILE: FSNotes/ProjectSettingsViewController.swift
================================================
//
// ProjectSettingsViewController.swift
// FSNotes
//
// Created by Oleksandr Glushchenko on 11/23/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
import Carbon.HIToolbox
class ProjectSettingsViewController: SettingsViewController {
@IBOutlet weak var modificationDate: NSButton!
@IBOutlet weak var creationDate: NSButton!
@IBOutlet weak var titleButton: NSButton!
@IBOutlet weak var sortByGlobal: NSButton!
@IBOutlet weak var directionASC: NSButton!
@IBOutlet weak var directionDESC: NSButton!
@IBOutlet weak var showInAll: NSButton!
@IBOutlet weak var firstLineAsTitle: NSButton!
@IBOutlet weak var nestedFoldersContent: NSButton!
@IBOutlet weak var gitView: NSView!
@IBOutlet weak var gitViewHeight: NSLayoutConstraint!
override func viewDidLoad() {
gitView.isHidden = true
gitViewHeight.constant = 0
}
@IBAction func sortBy(_ sender: NSButton) {
guard let project = project else { return }
let sortBy = SortBy(rawValue: sender.identifier!.rawValue)!
project.settings.sortBy = sortBy
project.saveSettings()
guard let vc = ViewController.shared() else { return }
vc.buildSearchQuery()
vc.updateTable()
}
@IBAction func sortDirection(_ sender: NSButton) {
guard let project = project else { return }
project.settings.sortDirection = SortDirection(rawValue: sender.identifier!.rawValue)!
project.saveSettings()
guard let vc = ViewController.shared() else { return }
vc.buildSearchQuery()
vc.updateTable()
}
@IBAction func showNotesInMainList(_ sender: NSButton) {
project?.settings.showInCommon = sender.state == .on
project?.saveSettings()
}
@IBAction func firstLineAsTitle(_ sender: NSButton) {
guard let project = self.project else { return }
project.settings.firstLineAsTitle = sender.state == .on
project.saveSettings()
let notes = Storage.shared().getNotesBy(project: project)
for note in notes {
note.invalidateCache()
}
guard let vc = ViewController.shared() else { return }
vc.notesTableView.reloadData()
}
@IBAction func close(_ sender: Any) {
self.dismiss(nil)
}
@IBAction func showNestedFoldersContent(_ sender: NSButton) {
guard let project = self.project else { return }
project.settings.showNestedFoldersContent = sender.state == .on
project.saveSettings()
guard let vc = ViewController.shared() else { return }
vc.updateTable()
}
public func load(project: Project) {
self.project = project
if project.isVirtual {
showInAll.isEnabled = false
nestedFoldersContent.isEnabled = false
firstLineAsTitle.isEnabled = false
}
showInAll.state = project.settings.showInCommon ? .on : .off
firstLineAsTitle.state = project.settings.isFirstLineAsTitle() ? .on : .off
nestedFoldersContent.state = project.settings.showNestedFoldersContent ? .on : .off
modificationDate.state = project.settings.sortBy == .modificationDate ? .on : .off
creationDate.state = project.settings.sortBy == .creationDate ? .on : .off
titleButton.state = project.settings.sortBy == .title ? .on : .off
sortByGlobal.state = project.settings.sortBy == .none ? .on : .off
directionASC.state = project.settings.sortDirection == .asc ? .on : .off
directionDESC.state = project.settings.sortDirection == .desc ? .on : .off
if project.parent == nil && !project.isTrash && !project.isEncrypted {
gitView.isHidden = false
gitViewHeight.constant = 150
}
loadGit(project: project)
}
override func keyDown(with event: NSEvent) {
if event.keyCode == kVK_Return || event.keyCode == kVK_Escape {
self.dismiss(nil)
}
}
}
================================================
FILE: FSNotes/SidebarScrollView.swift
================================================
//
// SidebarScrollView.swift
// FSNotes
//
// Created by Oleksandr Glushchenko on 4/9/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
class SidebarNotesView: NSView {
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
layer?.backgroundColor = NSColor.white.cgColor
}
}
================================================
FILE: FSNotes/View/AboutImageView.swift
================================================
//
// AboutImage.swift
// FSNotes
//
// Created by Oleksandr Hlushchenko on 08.01.2023.
// Copyright © 2023 Oleksandr Hlushchenko. All rights reserved.
//
import Cocoa
class AboutImageView: NSImageView {
override func mouseEntered(with event: NSEvent) {
image = NSImage(named: "friend")
}
override func mouseExited(with event: NSEvent) {
image = NSImage(named: "modern")
}
override func updateTrackingAreas() {
super.updateTrackingAreas()
for trackingArea in self.trackingAreas {
self.removeTrackingArea(trackingArea)
}
let options: NSTrackingArea.Options = [.mouseEnteredAndExited, .activeAlways]
let trackingArea = NSTrackingArea(rect: self.bounds, options: options, owner: self, userInfo: nil)
self.addTrackingArea(trackingArea)
}
}
================================================
FILE: FSNotes/View/ClickableTextField.swift
================================================
//
// ClickableTextField.swift
// FSNotes
//
// Created by Oleksandr Hlushchenko on 13.08.2024.
// Copyright © 2024 Oleksandr Hlushchenko. All rights reserved.
//
import Cocoa
class ClickableTextField: NSTextField {
override func mouseDown(with event: NSEvent) {
super.mouseDown(with: event)
guard let vc = ViewController.shared(),
let projects = vc.sidebarOutlineView.getSelectedProjects() else { return }
vc.getMasterPassword() { password in
vc.sidebarOutlineView.unlock(projects: projects, password: password, action: nil)
}
}
}
================================================
FILE: FSNotes/View/EditTextView+Clicked.swift
================================================
//
// EditTextView+Clicked.swift
// FSNotes
//
// Created by Oleksandr Hlushchenko on 13.12.2025.
// Copyright © 2025 Oleksandr Hlushchenko. All rights reserved.
//
import Foundation
import AppKit
extension EditTextView {
public func handleEmailLink(_ link: Any) -> Bool {
guard let emailString = link as? String,
emailString.isValidEmail(),
let mailURL = URL(string: "mailto:\(emailString)") else {
return false
}
NSWorkspace.shared.open(mailURL)
return true
}
public func handleAnchorLink(_ link: Any) -> Bool {
guard let linkString = link as? String,
linkString.startsWith(string: "#") else {
return false
}
let title = String(linkString.dropFirst()).replacingOccurrences(of: "-", with: " ")
guard let textRange = textStorage?.string.range(of: "# " + title),
let nsRange = textStorage?.string.nsRange(from: textRange) else {
return false
}
setSelectedRange(nsRange)
scrollRangeToVisible(nsRange)
return true
}
public func isAttachmentAtPosition(_ charIndex: Int) -> Bool {
let range = NSRange(location: charIndex, length: 1)
let char = attributedSubstring(forProposedRange: range, actualRange: nil)
return char?.attribute(.attachment, at: 0, effectiveRange: nil) != nil
}
public func handleRegularLink(_ link: Any, at charIndex: Int) -> Bool {
guard let url = convertToURL(link) else {
super.clicked(onLink: link, at: charIndex)
return true
}
// Handle file:// URLs
if url.scheme == "file" {
DispatchQueue.main.async {
NSWorkspace.shared.activateFileViewerSelecting([url])
}
return true
}
// Handle non-fsnotes URLs with modifiers
if url.scheme != "fsnotes" {
if let handled = handleURLWithModifiers(url, at: charIndex) {
return handled
}
}
super.clicked(onLink: link, at: charIndex)
return true
}
private func convertToURL(_ link: Any) -> URL? {
if let url = link as? URL {
return url
}
if let linkString = link as? String {
return linkString.createURL(for: self.note)
}
return nil
}
private func handleURLWithModifiers(_ url: URL, at charIndex: Int) -> Bool? {
guard let event = NSApp.currentEvent else {
return nil
}
// Shift: Open without activation
if event.modifierFlags.contains(.shift) {
let configuration = NSWorkspace.OpenConfiguration()
configuration.activates = false
NSWorkspace.shared.open(url, configuration: configuration, completionHandler: nil)
return true
}
// Command: Open normally
if event.modifierFlags.contains(.command) {
NSWorkspace.shared.open(url)
return true
}
// No modifier: Check user preferences
if !UserDefaultsManagement.clickableLinks {
setSelectedRange(NSRange(location: charIndex, length: 0))
return true
}
return nil
}
}
================================================
FILE: FSNotes/View/EditTextView+Complete.swift
================================================
//
// EditTextView+Complete.swift
// FSNotes
//
// Created by Oleksandr Hlushchenko on 06.12.2025.
// Copyright © 2025 Oleksandr Hlushchenko. All rights reserved.
//
import Foundation
import AppKit
// MARK: - Completion Context
enum CompletionContext: Equatable {
case wikiLink(startPos: Int)
case tag(startPos: Int)
case codeBlock(startPos: Int)
case none
var startPosition: Int? {
switch self {
case .wikiLink(let pos), .tag(let pos), .codeBlock(let pos):
return pos
case .none:
return nil
}
}
}
extension EditTextView {
// MARK: - Context Detection
func detectCompletionContext() -> CompletionContext {
let location = selectedRange().location
let text = string as NSString
if let codeBlockContext = detectCodeBlockContext(at: location, in: text) {
return codeBlockContext
}
// Disable completion in code blocks
guard let ranges = note?.codeBlockRangesCache,
!ranges.contains(where: { $0.contains(location) }) else { return .none }
if let tagContext = detectTagContext(at: location, in: text) {
return tagContext
}
if let wikiContext = detectWikiContext(at: location, in: text) {
return wikiContext
}
return .none
}
private func detectCodeBlockContext(at location: Int, in text: NSString) -> CompletionContext? {
guard location >= 3 else { return nil }
guard let ranges = note?.codeBlockRangesCache,
ranges.contains(where: { $0.contains(location) })
|| (
// Allow if no code block before
!ranges.contains(where: { $0.contains(location - 1) }) &&
!ranges.contains(where: { $0.contains(location) })
)
else {
return nil
}
let checkRange = NSRange(location: location - 3, length: 3)
let lastChars = text.substring(with: checkRange)
guard lastChars == "```" else {
return detectCodeBlockLanguageInput(at: location, in: text)
}
let lineStart = findLineStart(at: location - 3, in: text)
if lineStart < location - 3 {
let beforeRange = NSRange(location: lineStart, length: location - 3 - lineStart)
let beforeText = text.substring(with: beforeRange)
for char in beforeText {
if char != " " && char != "\t" {
return nil
}
}
}
return .codeBlock(startPos: location)
}
private func detectCodeBlockLanguageInput(at location: Int, in text: NSString) -> CompletionContext? {
var searchPos = location - 1
while searchPos >= 0 && location - searchPos < 30 {
if searchPos + 3 <= text.length {
let checkRange = NSRange(location: searchPos, length: 3)
let chars = text.substring(with: checkRange)
if chars == "```" {
let lineStart = findLineStart(at: searchPos, in: text)
if lineStart < searchPos {
let beforeRange = NSRange(location: lineStart, length: searchPos - lineStart)
let beforeText = text.substring(with: beforeRange)
var isValidStart = true
for char in beforeText {
if char != " " && char != "\t" {
isValidStart = false
break
}
}
if !isValidStart {
return nil
}
}
let betweenRange = NSRange(location: searchPos + 3, length: location - searchPos - 3)
let betweenText = text.substring(with: betweenRange)
if !betweenText.contains("\n") {
return .codeBlock(startPos: searchPos + 3)
}
return nil
}
}
searchPos -= 1
}
return nil
}
private func findLineStart(at position: Int, in text: NSString) -> Int {
var pos = position - 1
while pos >= 0 {
let char = text.substring(with: NSRange(location: pos, length: 1))
if char == "\n" {
return pos + 1
}
pos -= 1
}
return 0
}
private func detectTagContext(at location: Int, in text: NSString) -> CompletionContext? {
guard UserDefaultsManagement.inlineTags && location >= 1 else { return nil }
var searchPos = location - 1
while searchPos >= 0 && location - searchPos < 50 {
let char = text.substring(with: NSRange(location: searchPos, length: 1))
if char == "#" {
if isValidTagStart(at: searchPos, in: text) {
return .tag(startPos: searchPos)
}
break
} else if isWhitespace(char) {
break
}
searchPos -= 1
}
return nil
}
private func detectWikiContext(at location: Int, in text: NSString) -> CompletionContext? {
var searchPos = location
while searchPos >= 2 && location - searchPos < 100 {
let checkRange = NSRange(location: searchPos - 2, length: 2)
let chars = text.substring(with: checkRange)
if chars == "[[" {
let betweenRange = NSRange(location: searchPos, length: location - searchPos)
let betweenText = text.substring(with: betweenRange)
if !betweenText.contains("]]") {
return .wikiLink(startPos: searchPos)
}
}
searchPos -= 1
}
return nil
}
// MARK: - Helpers
private func isValidTagStart(at position: Int, in text: NSString) -> Bool {
guard position >= 0 else { return false }
if position == 0 {
return true
}
let charBefore = text.substring(with: NSRange(location: position - 1, length: 1))
return isWhitespace(charBefore)
}
private func isWhitespace(_ char: String) -> Bool {
return char == " " || char == "\n" || char == "\t"
}
private func checkForClosingBrackets(at position: Int, in text: NSString) -> Bool {
guard position + 2 <= text.length else { return false }
let nextRange = NSRange(location: position, length: 2)
let nextChars = text.substring(with: nextRange)
return nextChars == "]]"
}
// MARK: - Completion Handlers
func handleCompletions(index: UnsafeMutablePointer) -> [String]? {
let context = detectCompletionContext()
let currentPos = selectedRange().location
let text = string as NSString
index.pointee = 0
switch context {
case .codeBlock(let startPos):
return getCodeBlockCompletions(startPos: startPos, currentPos: currentPos, text: text)
case .tag(let startPos):
return getTagCompletions(startPos: startPos, currentPos: currentPos, text: text)
case .wikiLink(let startPos):
return getWikiCompletions(startPos: startPos, currentPos: currentPos, text: text)
case .none:
return nil
}
}
private func getCodeBlockCompletions(startPos: Int, currentPos: Int, text: NSString) -> [String]? {
let searchLength = currentPos - startPos
let codeLanguages = NotesTextProcessor.getHighlighter().getLanguages()
.sorted()
if searchLength == 0 {
return codeLanguages
}
let searchRange = NSRange(location: startPos, length: searchLength)
let searchText = text.substring(with: searchRange)
let filtered = codeLanguages
.filter { $0.localizedCaseInsensitiveContains(searchText) }
.sorted { a, b in
let aStarts = a.range(of: searchText, options: [.caseInsensitive, .anchored]) != nil
let bStarts = b.range(of: searchText, options: [.caseInsensitive, .anchored]) != nil
if aStarts != bStarts {
return aStarts && !bStarts
}
return a.localizedCaseInsensitiveCompare(b) == .orderedAscending
}
return filtered.isEmpty ? nil : filtered
}
private func getTagCompletions(startPos: Int, currentPos: Int, text: NSString) -> [String]? {
let searchLength = currentPos - startPos - 1
if searchLength == 0 {
if let tags = viewDelegate?.sidebarOutlineView.getAllTags() {
return tags.sorted()
}
}
let searchRange = NSRange(location: startPos + 1, length: searchLength)
let searchText = text.substring(with: searchRange)
if let tags = viewDelegate?.sidebarOutlineView.getAllTags() {
let filtered = tags
.filter { $0.startsWith(string: searchText) }
.sorted()
return filtered.isEmpty ? nil : filtered
}
return nil
}
private func getWikiCompletions(startPos: Int, currentPos: Int, text: NSString) -> [String]? {
let searchLength = currentPos - startPos
if searchLength == 0 {
let titles = storage.noteList
.map { String($0.title) }
.filter { !$0.isEmpty }
.sorted()
return titles
}
let searchRange = NSRange(location: startPos, length: searchLength)
let searchText = text.substring(with: searchRange)
if let notes = storage.getBy(contains: searchText) {
let titles = notes
.map { String($0.title) }
.filter { $0.localizedCaseInsensitiveContains(searchText) && !$0.isEmpty && $0 != searchText }
.sorted()
return titles
}
return nil
}
func handleInsertCompletion(word: String, movement: Int, isFinal flag: Bool) {
guard flag && movement == NSReturnTextMovement else {
return
}
let context = detectCompletionContext()
switch context {
case .codeBlock(let startPos):
insertCodeBlockCompletion(word, startPos: startPos)
case .tag(let startPos):
insertTagCompletion(word, startPos: startPos)
case .wikiLink(let startPos):
insertWikiCompletion(word, startPos: startPos)
case .none:
break
}
}
private func insertCodeBlockCompletion(_ word: String, startPos: Int) {
let currentPos = selectedRange().location
let replaceRange = NSRange(location: startPos, length: currentPos - startPos)
let nextLineRange = NSRange(location: currentPos + 1, length: 3)
let nextLine = (self.string as NSString)
.safeSubstring(with: nextLineRange)
.trimmingCharacters(in: .whitespacesAndNewlines)
let nextLineHasBackticks = (nextLine == "```")
var completion = nextLineHasBackticks
? "\(word)\n"
: "\(word)\n\n```"
// Inside code block without ```
if let ranges = note?.codeBlockRangesCache {
for r in ranges where r.contains(startPos) {
completion = word
break
}
}
suppressCompletion = true
if shouldChangeText(in: replaceRange, replacementString: completion) {
replaceCharacters(in: replaceRange, with: completion)
didChangeText()
setSelectedRange(NSRange(location: startPos + word.count + 1, length: 0))
}
}
private func insertTagCompletion(_ word: String, startPos: Int) {
let currentPos = selectedRange().location
let replaceRange = NSRange(location: startPos + 1, length: currentPos - startPos - 1)
if shouldChangeText(in: replaceRange, replacementString: word) {
replaceCharacters(in: replaceRange, with: word)
let spacePos = startPos + 1 + word.count
if shouldChangeText(in: NSRange(location: spacePos, length: 0), replacementString: " ") {
replaceCharacters(in: NSRange(location: spacePos, length: 0), with: " ")
}
didChangeText()
let newPos = startPos + 1 + word.count + 1
setSelectedRange(NSRange(location: newPos, length: 0))
}
}
private func insertWikiCompletion(_ word: String, startPos: Int) {
let text = string as NSString
let currentPos = selectedRange().location
let hasClosingBrackets = checkForClosingBrackets(at: currentPos, in: text)
let replaceRange = NSRange(location: startPos, length: currentPos - startPos)
let completion = hasClosingBrackets ? word : "\(word)]]"
if shouldChangeText(in: replaceRange, replacementString: completion) {
replaceCharacters(in: replaceRange, with: completion)
didChangeText()
let newPos = hasClosingBrackets ? startPos + word.count + 2 : startPos + completion.count
setSelectedRange(NSRange(location: newPos, length: 0))
}
}
func calculateCompletionRange() -> NSRange {
let location = selectedRange().location
let context = detectCompletionContext()
switch context {
case .codeBlock(let startPos):
return NSRange(location: startPos, length: location - startPos)
case .tag(let startPos):
return NSRange(location: startPos + 1, length: location - startPos - 1)
case .wikiLink(let startPos):
return NSRange(location: startPos, length: location - startPos)
case .none:
return NSRange(location: location, length: 0)
}
}
}
extension NSString {
func safeSubstring(with range: NSRange) -> String {
let length = self.length
if length == 0 { return "" }
let safeLocation = max(0, min(range.location, length - 1))
let safeLength = max(0, min(range.length, length - safeLocation))
if safeLength == 0 { return "" }
let safeRange = NSRange(location: safeLocation, length: safeLength)
return self.substring(with: safeRange)
}
}
================================================
FILE: FSNotes/View/EditTextView+DragOperation.swift
================================================
//
// EditTextView+DragOperation.swift
// FSNotes
//
// Created by Oleksandr Hlushchenko on 15.10.2025.
// Copyright © 2025 Oleksandr Hlushchenko. All rights reserved.
//
import Cocoa
extension EditTextView
{
public func handleAttributedText(_ pasteboard: NSPasteboard, note: Note, storage: NSTextStorage, replacementRange: NSRange) -> Bool {
let locationDiff = selectedRange().location > replacementRange.location
? replacementRange.location
: replacementRange.location - selectedRange().length
let insertRange = NSRange(location: locationDiff, length: 0)
let removeRange = selectedRange()
// drag
insertText("", replacementRange: removeRange)
guard let data = pasteboard.data(forType: NSPasteboard.attributed),
let attributedString = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as? NSAttributedString else { return false }
// drop
insertText(attributedString, replacementRange: insertRange)
// select
let selectedRange = NSRange(location: locationDiff, length: attributedString.length)
setSelectedRange(selectedRange)
return true
}
public func handleNoteReference(_ pasteboard: NSPasteboard, note: Note, replacementRange: NSRange) -> Bool {
guard
let archivedData = pasteboard.data(forType: NSPasteboard.note),
let urls = try? NSKeyedUnarchiver.unarchivedObject(ofClasses: [NSArray.self, NSURL.self], from: archivedData) as? [URL],
let url = urls.first,
let draggableNote = Storage.shared().getBy(url: url),
let textStorage = self.textStorage
else { return false }
let title = "[[\(draggableNote.title)]]"
DispatchQueue.main.async {
self.window?.makeFirstResponder(self)
guard let undoManager = self.undoManager else { return }
undoManager.beginUndoGrouping()
if self.shouldChangeText(in: replacementRange, replacementString: title) {
textStorage.replaceCharacters(in: replacementRange, with: title)
self.didChangeText()
self.setSelectedRange(NSRange(location: replacementRange.location + title.count, length: 0))
}
undoManager.endUndoGrouping()
undoManager.setActionName("Insert Note Reference")
}
return true
}
public func handleURLs(_ pasteboard: NSPasteboard, note: Note, replacementRange: NSRange) -> Bool {
guard let urls = pasteboard.readObjects(forClasses: [NSURL.self]) as? [URL],
!urls.isEmpty else { return false }
note.save(attributed: attributedString())
let group = DispatchGroup()
let total = urls.count
var results = Array(repeating: nil, count: total)
for (index, url) in urls.enumerated() {
group.enter()
fetchDataFromURL(url: url) { data, error in
defer { group.leave() }
guard let data = data, error == nil else { return }
if url.isWebURL {
let title = self.getHTMLTitle(from: data) ?? url.lastPathComponent
let text = "[\(title)](\(url.absoluteString))"
results[index] = NSAttributedString(string: text)
} else if let filePath = ImagesProcessor.writeFile(data: data, url: url, note: note),
let fileURL = note.getAttachmentFileUrl(
name: filePath.removingPercentEncoding ?? filePath
) {
let attributed = NSMutableAttributedString(
url: fileURL,
title: "",
path: filePath
)
results[index] = attributed
}
}
}
group.notify(queue: .main) {
let final = NSMutableAttributedString()
for i in 0.. 0 else { return }
let selectedRange = selectedRange()
let lineRange = textStorage.mutableString.lineRange(for: selectedRange)
if lineRange.location == 0 {
NSSound.beep()
return
}
let previousLineStart = textStorage.mutableString.lineRange(
for: NSRange(location: lineRange.location - 1, length: 0)
).location
let previousLineRange = NSRange(
location: previousLineStart,
length: lineRange.location - previousLineStart
)
let currentLinesAttr = textStorage.attributedSubstring(from: lineRange)
let previousLineAttr = textStorage.attributedSubstring(from: previousLineRange)
let offsetInLine = selectedRange.location - lineRange.location
let currentLinesString = currentLinesAttr.string
let needsNewline = !currentLinesString.hasSuffix("\n")
let newContent = NSMutableAttributedString()
newContent.append(currentLinesAttr)
if needsNewline {
let attrs = currentLinesAttr.length > 0
? currentLinesAttr.attributes(at: currentLinesAttr.length - 1, effectiveRange: nil)
: [:]
newContent.append(NSAttributedString(string: "\n", attributes: attrs))
}
var previousToAppend = previousLineAttr
if needsNewline && previousLineAttr.string.hasSuffix("\n") {
let trimmedPrevious = NSMutableAttributedString(attributedString: previousLineAttr)
trimmedPrevious.deleteCharacters(in: NSRange(location: trimmedPrevious.length - 1, length: 1))
previousToAppend = trimmedPrevious
}
newContent.append(previousToAppend)
let combinedRange = NSRange(
location: previousLineRange.location,
length: previousLineRange.length + lineRange.length
)
newContent.saveData()
if shouldChangeText(in: combinedRange, replacementString: newContent.string) {
insertText(newContent, replacementRange: combinedRange)
didChangeText()
}
let newSelectionLocation = previousLineRange.location + offsetInLine
setSelectedRange(NSRange(
location: newSelectionLocation,
length: selectedRange.length
))
scrollRangeToVisible(self.selectedRange())
}
func moveSelectedLinesDown() {
guard let textStorage = textStorage,
textStorage.length > 0 else { return }
let selectedRange = selectedRange()
let lineRange = textStorage.mutableString.lineRange(for: selectedRange)
if NSMaxRange(lineRange) >= textStorage.length {
NSSound.beep()
return
}
let nextLineRange = textStorage.mutableString.lineRange(
for: NSRange(location: NSMaxRange(lineRange), length: 0)
)
let currentLinesAttr = textStorage.attributedSubstring(from: lineRange)
let nextLineAttr = textStorage.attributedSubstring(from: nextLineRange)
let offsetInLine = selectedRange.location - lineRange.location
let nextLineString = nextLineAttr.string
let needsNewline = !nextLineString.hasSuffix("\n")
let newContent = NSMutableAttributedString()
var nextLineFinalLength = nextLineAttr.length
newContent.append(nextLineAttr)
if needsNewline {
let attrs = nextLineAttr.length > 0
? nextLineAttr.attributes(at: nextLineAttr.length - 1, effectiveRange: nil)
: [:]
newContent.append(NSAttributedString(string: "\n", attributes: attrs))
nextLineFinalLength += 1
}
var currentToAppend = currentLinesAttr
if needsNewline && currentLinesAttr.string.hasSuffix("\n") {
let trimmedCurrent = NSMutableAttributedString(attributedString: currentLinesAttr)
trimmedCurrent.deleteCharacters(in: NSRange(location: trimmedCurrent.length - 1, length: 1))
currentToAppend = trimmedCurrent
}
newContent.append(currentToAppend)
let combinedRange = NSRange(
location: lineRange.location,
length: lineRange.length + nextLineRange.length
)
newContent.saveData()
if shouldChangeText(in: combinedRange, replacementString: newContent.string) {
textStorage.replaceCharacters(in: combinedRange, with: newContent)
didChangeText()
}
let newSelectionLocation = lineRange.location + nextLineFinalLength + offsetInLine
setSelectedRange(NSRange(
location: newSelectionLocation,
length: selectedRange.length
))
scrollRangeToVisible(self.selectedRange())
}
}
================================================
FILE: FSNotes/View/EditTextView+Todo.swift
================================================
//
// EditTextView+Todo.swift
// FSNotes
//
// Created by Oleksandr Hlushchenko on 15.12.2025.
// Copyright © 2025 Oleksandr Hlushchenko. All rights reserved.
//
import Cocoa
extension EditTextView {
func clearCompletedTodos() {
guard let textStorage = textStorage else { return }
let fullRange = NSRange(location: 0, length: textStorage.length)
let text = textStorage.string as NSString
undoManager?.beginUndoGrouping()
var linesToRemove: [NSRange] = []
textStorage.enumerateAttribute(.todo, in: fullRange, options: []) { value, range, stop in
if let value = value as? Int, value == 1 {
let lineRange = text.lineRange(for: range)
if !linesToRemove.contains(where: { $0.intersection(lineRange) != nil }) {
linesToRemove.append(lineRange)
}
}
}
for lineRange in linesToRemove.sorted(by: { $0.location > $1.location }) {
if shouldChangeText(in: lineRange, replacementString: "") {
textStorage.replaceCharacters(in: lineRange, with: "")
didChangeText()
}
}
undoManager?.endUndoGrouping()
undoManager?.setActionName("Remove TODO Lines")
}
}
================================================
FILE: FSNotes/View/EditTextView.swift
================================================
//
// EditTextView.swift
// FSNotes
//
// Created by Oleksandr Glushchenko on 8/11/17.
// Copyright © 2017 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
import Carbon.HIToolbox
class EditTextView: NSTextView, NSTextFinderClient, NSSharingServicePickerDelegate {
public var editorViewController: EditorViewController?
public var textStorageProcessor: TextStorageProcessor?
public var note: Note?
public var viewDelegate: ViewController?
let storage = Storage.shared()
let caretWidth: CGFloat = 2
var downView: MPreviewView?
public var timer: Timer?
public var tagsTimer: Timer?
public var markdownView: MPreviewContainerView?
public var isLastEdited: Bool = false
@IBOutlet weak var previewMathJax: NSMenuItem!
public var imagesLoaderQueue = OperationQueue.init()
public var attributesCachingQueue = OperationQueue.init()
private var preview = false
public var isScrollPositionSaverLocked = false
override func becomeFirstResponder() -> Bool {
if let note = self.note {
if note.container == .encryptedTextPack {
return false
}
textStorage?.removeHighlight()
}
loadSelectedRange()
return super.becomeFirstResponder()
}
//MARK: caret width
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
guard UserDefaultsManagement.inlineTags else { return }
if #available(OSX 10.16, *) {
guard let textStorage = self.textStorage,
let layoutManager = self.layoutManager
else { return }
let fullRange = NSRange(location: 0, length: textStorage.length)
attributedString().enumerateAttributes(in: fullRange, options: .reverse) { attributes, range, _ in
guard range.location >= 0,
range.location + range.length <= textStorage.length else { return }
guard attributes.index(forKey: .tag) != nil,
let font = attributes[.font] as? NSFont
else { return }
let tag = attributedString().attributedSubstring(from: range).string
let tagAttributes = attributedString().attributes(at: range.location, effectiveRange: nil)
let glyphRange = layoutManager.glyphRange(forCharacterRange: range, actualCharacterRange: nil)
let ascent = font.ascender
let descent = abs(font.descender)
let fontHeight = ascent + descent
layoutManager.enumerateLineFragments(forGlyphRange: glyphRange) { rect, usedRect, textContainer, lineGlyphRange, stop in
let intersectionRange = NSIntersectionRange(glyphRange, lineGlyphRange)
guard intersectionRange.length > 0 else { return }
var fragmentRect = layoutManager.boundingRect(forGlyphRange: intersectionRange, in: textContainer)
fragmentRect.origin.x += self.textContainerOrigin.x
fragmentRect.origin.y += self.textContainerOrigin.y
fragmentRect = self.convertToLayer(fragmentRect)
fragmentRect = fragmentRect.integral
let verticalInset = max(0, (fragmentRect.height - fontHeight) / 2)
var tagRect = NSRect(
x: fragmentRect.minX,
y: fragmentRect.minY + verticalInset,
width: fragmentRect.width - 3,
height: fontHeight
)
let oneCharSize = ("A" as NSString).size(withAttributes: tagAttributes)
tagRect.size.width += oneCharSize.width * 0.25
tagRect = tagRect.integral
NSGraphicsContext.saveGraphicsState()
let path = NSBezierPath(roundedRect: tagRect, xRadius: 3, yRadius: 3)
NSColor.tagColor.setFill()
path.fill()
let fragmentCharRange = layoutManager.characterRange(forGlyphRange: intersectionRange, actualGlyphRange: nil)
let fragmentText = (tag as NSString).substring(with: NSRange(
location: fragmentCharRange.location - range.location,
length: fragmentCharRange.length
))
var drawAttrs = tagAttributes
drawAttrs[.font] = font
drawAttrs[.foregroundColor] = NSColor.white
drawAttrs.removeValue(forKey: .link)
drawAttrs.removeValue(forKey: .baselineOffset)
let baselineOrigin = NSPoint(x: tagRect.minX, y: tagRect.minY + descent - 3)
(fragmentText as NSString).draw(at: baselineOrigin, withAttributes: drawAttrs)
NSGraphicsContext.restoreGraphicsState()
}
}
}
}
public func initTextStorage() {
let processor = TextStorageProcessor()
processor.editor = self
textStorageProcessor = processor
textStorage?.delegate = processor
guard let textStorage = self.textStorage,
let oldLayoutManager = self.layoutManager,
let textContainer = self.textContainer else { return }
textStorage.removeLayoutManager(oldLayoutManager)
let customLayoutManager = LayoutManager()
customLayoutManager.addTextContainer(textContainer)
customLayoutManager.delegate = customLayoutManager
customLayoutManager.processor = processor
textStorage.addLayoutManager(customLayoutManager)
}
public func configure() {
DispatchQueue.main.async {
self.updateTextContainerInset()
}
attributesCachingQueue.qualityOfService = .background
textContainerInset.height = 10
isEditable = false
let isOpenedWindow = window?.contentViewController as? NoteViewController != nil
layoutManager?.allowsNonContiguousLayout =
isOpenedWindow
? false
: UserDefaultsManagement.nonContiguousLayout
layoutManager?.defaultAttachmentScaling = .scaleProportionallyDown
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = CGFloat(UserDefaultsManagement.editorLineSpacing)
defaultParagraphStyle = paragraphStyle
typingAttributes[.paragraphStyle] = paragraphStyle
typingAttributes[.font] = UserDefaultsManagement.noteFont
}
public func invalidateLayout() {
if let length = self.textStorage?.length {
self.textStorage?.layoutManagers.first?.invalidateLayout(forCharacterRange: NSRange(location: 0, length: length), actualCharacterRange: nil)
}
}
func sharingServicePicker(_ sharingServicePicker: NSSharingServicePicker, sharingServicesForItems items: [Any], proposedSharingServices proposedServices: [NSSharingService]) -> [NSSharingService] {
return []
}
// MARK: Overrides
override func drawInsertionPoint(in rect: NSRect, color: NSColor, turnedOn flag: Bool) {
var newRect = rect
newRect.size.width = caretWidth
// Fixes last line height
if let textStorage = self.textStorage,
let layoutManager = self.layoutManager as? LayoutManager {
let insertionPoint = self.selectedRange().location
if insertionPoint == textStorage.length, insertionPoint > 0 {
let lastIndex = insertionPoint - 1
let attributes = textStorage.attributes(at: lastIndex, effectiveRange: nil)
let isNewline: Bool = {
let ns = textStorage.string as NSString
return ns.character(at: lastIndex) == 0x0A // '\n'
}()
let fontToUse: NSFont
if !isNewline, let font = attributes[.font] as? NSFont {
fontToUse = font
} else {
fontToUse = UserDefaultsManagement.noteFont
}
newRect.size.height = layoutManager.lineHeight(for: fontToUse)
}
}
let clr = NSColor(red: 0.47, green: 0.53, blue: 0.69, alpha: 1.0)
super.drawInsertionPoint(in: newRect, color: clr, turnedOn: flag)
}
override func updateInsertionPointStateAndRestartTimer(_ restartFlag: Bool) {
super.updateInsertionPointStateAndRestartTimer(true)
}
override func setNeedsDisplay(_ invalidRect: NSRect) {
var newInvalidRect = NSRect(origin: invalidRect.origin, size: invalidRect.size)
newInvalidRect.size.width += self.caretWidth - 1
super.setNeedsDisplay(newInvalidRect)
}
override func toggleContinuousSpellChecking(_ sender: Any?) {
if let menu = sender as? NSMenuItem {
UserDefaultsManagement.continuousSpellChecking = (menu.state == .off)
}
super.toggleContinuousSpellChecking(sender)
}
override func toggleGrammarChecking(_ sender: Any?) {
if let menu = sender as? NSMenuItem {
UserDefaultsManagement.grammarChecking = (menu.state == .off)
}
super.toggleGrammarChecking(sender)
}
override func toggleAutomaticSpellingCorrection(_ sender: Any?) {
if let menu = sender as? NSMenuItem {
UserDefaultsManagement.automaticSpellingCorrection = (menu.state == .off)
}
super.toggleAutomaticSpellingCorrection(sender)
}
override func toggleSmartInsertDelete(_ sender: Any?) {
if let menu = sender as? NSMenuItem {
UserDefaultsManagement.smartInsertDelete = (menu.state == .off)
}
super.toggleSmartInsertDelete(sender)
}
override func toggleAutomaticQuoteSubstitution(_ sender: Any?) {
if let menu = sender as? NSMenuItem {
UserDefaultsManagement.automaticQuoteSubstitution = (menu.state == .off)
}
super.toggleAutomaticQuoteSubstitution(sender)
}
override func toggleAutomaticDataDetection(_ sender: Any?) {
if let menu = sender as? NSMenuItem {
UserDefaultsManagement.automaticDataDetection = (menu.state == .off)
}
super.toggleAutomaticDataDetection(sender)
}
override func toggleAutomaticLinkDetection(_ sender: Any?) {
if let menu = sender as? NSMenuItem {
UserDefaultsManagement.automaticLinkDetection = (menu.state == .off)
}
super.toggleAutomaticLinkDetection(sender)
}
override func toggleAutomaticTextReplacement(_ sender: Any?) {
if let menu = sender as? NSMenuItem {
UserDefaultsManagement.automaticTextReplacement = (menu.state == .off)
}
super.toggleAutomaticTextReplacement(sender)
}
override func toggleAutomaticDashSubstitution(_ sender: Any?) {
if let menu = sender as? NSMenuItem {
UserDefaultsManagement.automaticDashSubstitution = (menu.state == .off)
}
super.toggleAutomaticDashSubstitution(sender)
}
private var dragDetected = false
override func mouseDown(with event: NSEvent) {
guard let note = self.note else { return }
guard note.container != .encryptedTextPack else {
editorViewController?.unLock(notes: [note])
editorViewController?.vcNonSelectedLabel?.isHidden = false
return
}
if editorViewController?.vcEditor?.isPreviewEnabled() == false {
self.isEditable = true
}
let range = selectedRange
if handleTodo(event) {
self.window?.makeFirstResponder(self)
setSelectedRange(range)
self.window?.makeFirstResponder(nil)
return
}
dragDetected = false
super.mouseDown(with: event)
saveSelectedRange()
if !self.dragDetected {
self.handleClick(event)
self.dragDetected = false
}
}
private func handleTodo(_ event: NSEvent) -> Bool {
guard let container = self.textContainer,
let manager = self.layoutManager
else { return false }
let point = self.convert(event.locationInWindow, from: nil)
let properPoint = NSPoint(x: point.x - textContainerInset.width, y: point.y)
let index = manager.characterIndex(for: properPoint, in: container, fractionOfDistanceBetweenInsertionPoints: nil)
let glyphRect = manager.boundingRect(forGlyphRange: NSRange(location: index, length: 1), in: container)
guard glyphRect.contains(properPoint) else { return false }
if isTodo(index) {
guard let f = self.getTextFormatter() else { return false }
f.toggleTodo(index)
DispatchQueue.main.async {
NSCursor.pointingHand.set()
}
return true
}
return false
}
private func handleClick(_ event: NSEvent) {
guard let container = self.textContainer,
let manager = self.layoutManager
else { return }
let point = self.convert(event.locationInWindow, from: nil)
let properPoint = NSPoint(x: point.x - textContainerInset.width, y: point.y)
let index = manager.characterIndex(for: properPoint, in: container, fractionOfDistanceBetweenInsertionPoints: nil)
let glyphRect = manager.boundingRect(forGlyphRange: NSRange(location: index, length: 1), in: container)
guard glyphRect.contains(properPoint) else { return }
if hasAttachment(at: index) {
if event.modifierFlags.contains(.command) {
openTitleEditor(at: index)
} else {
openFileViewer(at: index)
}
return
}
}
private func openTitleEditor(at: Int) {
guard let vc = editorViewController,
let window = vc.view.window,
var attachment = getAttachment(at: at) else { return }
vc.alert = NSAlert()
let field = NSTextField(frame: NSRect(x: 0, y: 0, width: 290, height: 20))
field.placeholderString = "All Hail the Crimson King"
field.stringValue = attachment.title
vc.alert?.messageText = NSLocalizedString("Please enter image title:", comment: "Edit area")
vc.alert?.accessoryView = field
vc.alert?.alertStyle = .informational
vc.alert?.addButton(withTitle: "OK")
vc.alert?.beginSheetModal(for: window) { (returnCode: NSApplication.ModalResponse) -> Void in
if returnCode == NSApplication.ModalResponse.alertFirstButtonReturn {
attachment.title = field.stringValue
var range = NSRange()
if self.textStorage?.attribute(.attachment, at: at, effectiveRange: &range) as? NSTextAttachment != nil {
self.textStorage?.addAttribute(.attachmentTitle, value: attachment.title, range: range)
let content = NSMutableAttributedString(attributedString: self.attributedString())
_ = self.note?.save(content: content)
}
}
vc.alert = nil
}
DispatchQueue.main.async {
field.becomeFirstResponder()
}
}
private func openFileViewer(at: Int) {
guard let attachment = getAttachment(at: at) else { return }
let url = attachment.url
if !url.isImage {
NSWorkspace.shared.activateFileViewerSelecting([url])
return
}
NSWorkspace.shared.open(url)
}
override func mouseMoved(with event: NSEvent) {
if editorViewController?.vcNonSelectedLabel?.isHidden == false {
NSCursor.arrow.set()
return
}
let point = self.convert(event.locationInWindow, from: nil)
let properPoint = NSPoint(
x: point.x - textContainerInset.width,
y: point.y - textContainerInset.height
)
guard let container = self.textContainer,
let manager = self.layoutManager,
let textStorage = self.textStorage else { return }
let index = manager.characterIndex(for: properPoint, in: container, fractionOfDistanceBetweenInsertionPoints: nil)
guard index < textStorage.length else { return }
let glyphRect = manager.boundingRect(forGlyphRange: NSRange(location: index, length: 1), in: container)
if glyphRect.contains(properPoint), self.isTodo(index) || self.hasAttachment(at: index) {
NSCursor.pointingHand.set()
return
}
if glyphRect.contains(properPoint),
let link = textStorage.attribute(.link, at: index, effectiveRange: nil) {
if textStorage.attribute(.tag, at: index, effectiveRange: nil) != nil {
NSCursor.pointingHand.set()
return
}
if link as? URL != nil {
if UserDefaultsManagement.clickableLinks
|| event.modifierFlags.contains(.command)
|| event.modifierFlags.contains(.shift)
{
NSCursor.pointingHand.set()
return
}
NSCursor.iBeam.set()
return
}
}
if editorViewController?.vcEditor?.isPreviewEnabled() == true {
return
}
super.mouseMoved(with: event)
}
public func hasAttachment(at: Int) -> Bool {
guard let storage = textStorage,
at >= 0,
at < storage.length else { return false }
guard textStorage?.attribute(.attachment, at: at, effectiveRange: nil) as? NSTextAttachment != nil else {
return false
}
return textStorage?.getMeta(at: at) != nil
}
public func getAttachment(at: Int) -> (url: URL, title: String, path: String)? {
if textStorage?.attribute(.attachment, at: at, effectiveRange: nil) as? NSTextAttachment != nil,
let meta = textStorage?.getMeta(at: at) {
return meta
}
return nil
}
public func isTodo(_ location: Int) -> Bool {
guard let storage = self.textStorage else { return false }
let range = (storage.string as NSString).paragraphRange(for: NSRange(location: location, length: 0))
let string = storage.attributedSubstring(from: range).string as NSString
if storage.attribute(.todo, at: location, effectiveRange: nil) != nil {
return true
}
var length = string.range(of: "- [ ] ").length
if length == 0 {
length = string.range(of: "- [x] ").length
}
if length > 0 {
let upper = range.location + length
if location >= range.location && location <= upper {
return true
}
}
return false
}
override var writablePasteboardTypes: [NSPasteboard.PasteboardType] {
get {
return [
NSPasteboard.attributed,
NSPasteboard.PasteboardType.string,
]
}
}
override var readablePasteboardTypes: [NSPasteboard.PasteboardType] {
get {
return super.readablePasteboardTypes + [NSPasteboard.attributed]
}
}
override func writeSelection(to pboard: NSPasteboard, type: NSPasteboard.PasteboardType) -> Bool {
guard let storage = textStorage else { return false }
dragDetected = true
let range = selectedRange()
let attributedString = NSMutableAttributedString(attributedString: storage.attributedSubstring(from: range))
if type == .string {
let plainText = attributedString.unloadAttachments().string
pboard.setString(plainText, forType: .string)
return true
}
if type == NSPasteboard.attributed {
let attributedString = attributedString.unloadTasks()
attributedString.saveData()
if let data = try? NSKeyedArchiver.archivedData(
withRootObject: attributedString,
requiringSecureCoding: false
) {
pboard.setData(data, forType: NSPasteboard.attributed)
return true
}
}
return false
}
// Copy empty string
override func copy(_ sender: Any?) {
let attrString = attributedSubstring(forProposedRange: self.selectedRange, actualRange: nil)
if self.selectedRange.length == 1,
let url = attrString?.attribute(.attachmentUrl, at: 0, effectiveRange: nil) as? URL
{
let pb = NSPasteboard.general
pb.clearContents()
pb.writeObjects([url as NSURL])
return
}
if selectedRanges.count > 1 {
var combined = String()
for range in selectedRanges {
if let range = range as? NSRange, let sub = attributedSubstring(forProposedRange: range, actualRange: nil) as? NSMutableAttributedString {
combined.append(sub.unloadAttachments().string + "\n")
}
}
let pasteboard = NSPasteboard.general
pasteboard.declareTypes([NSPasteboard.PasteboardType.string], owner: nil)
pasteboard.setString(combined.trim().removeLastNewLine(), forType: NSPasteboard.PasteboardType.string)
return
}
if self.selectedRange.length == 0, let paragraphRange = self.getParagraphRange(), let paragraph = attributedSubstring(forProposedRange: paragraphRange, actualRange: nil) {
let pasteboard = NSPasteboard.general
pasteboard.declareTypes([NSPasteboard.PasteboardType.string], owner: nil)
pasteboard.setString(paragraph.string.trim().removeLastNewLine(), forType: NSPasteboard.PasteboardType.string)
return
}
if let menuItem = sender as? NSMenuItem,
menuItem.identifier?.rawValue == "copy:",
self.selectedRange.length > 0 {
let attrString = attributedSubstring(forProposedRange: self.selectedRange, actualRange: nil)
if let attrString = attrString,
let link = attrString.attribute(.link, at: 0, effectiveRange: nil) as? String {
let pasteboard = NSPasteboard.general
pasteboard.declareTypes([.string], owner: nil)
pasteboard.setString(link, forType: .string)
return
}
}
super.copy(sender)
}
override func paste(_ sender: Any?) {
guard let note = self.note else { return }
// RTFD
if let rtfdData = NSPasteboard.general.data(forType: NSPasteboard.attributed),
let attributed = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(rtfdData) as? NSAttributedString {
let mutable = NSMutableAttributedString(attributedString: attributed)
mutable.loadTasks()
breakUndoCoalescing()
insertText(mutable, replacementRange: selectedRange())
breakUndoCoalescing()
return
}
// Plain text
if let clipboard = NSPasteboard.general.string(forType: NSPasteboard.PasteboardType.string),
NSPasteboard.general.string(forType: NSPasteboard.PasteboardType.fileURL) == nil {
let attributed = NSMutableAttributedString(string: clipboard.trim())
attributed.loadTasks()
breakUndoCoalescing()
insertText(attributed, replacementRange: selectedRange())
breakUndoCoalescing()
return
}
if let url = NSURL(from: NSPasteboard.general) {
if url.isFileURL && saveFile(url: url as URL, in: note) {
return
}
}
// Images png or tiff
for type in [NSPasteboard.PasteboardType.png, .tiff] {
if let data = NSPasteboard.general.data(forType: type) {
guard let attributed = NSMutableAttributedString.build(data: data) else { continue }
breakUndoCoalescing()
insertText(attributed, replacementRange: selectedRange())
breakUndoCoalescing()
return
}
}
super.paste(sender)
}
override func pasteAsPlainText(_ sender: Any?) {
let currentRange = selectedRange()
var plainText: String?
if let rtfd = NSPasteboard.general.data(forType: NSPasteboard.attributed),
let attributedString = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(rtfd) as? NSAttributedString {
let mutable = NSMutableAttributedString(attributedString: attributedString)
plainText = mutable.unloadAttachments().string
} else if let clipboard = NSPasteboard.general.string(forType: NSPasteboard.PasteboardType.string), NSPasteboard.general.string(forType: NSPasteboard.PasteboardType.fileURL) == nil {
plainText = clipboard
} else if let url = NSPasteboard.general.string(forType: NSPasteboard.PasteboardType.fileURL) {
plainText = url
}
if let plainText = plainText {
self.breakUndoCoalescing()
self.insertText(plainText, replacementRange: currentRange)
self.breakUndoCoalescing()
return
}
return paste(sender)
}
override func cut(_ sender: Any?) {
guard nil != self.note else {
super.cut(sender)
return
}
if self.selectedRange.length == 0, let paragraphRange = self.getParagraphRange(), let paragraph = attributedSubstring(forProposedRange: paragraphRange, actualRange: nil) {
let pasteboard = NSPasteboard.general
pasteboard.declareTypes([NSPasteboard.PasteboardType.string], owner: nil)
pasteboard.setString(paragraph.string.trim().removeLastNewLine(), forType: NSPasteboard.PasteboardType.string)
insertText(String(), replacementRange: paragraphRange)
return
}
super.cut(sender)
}
func getSelectedNote() -> Note? {
return ViewController.shared()?.notesTableView?.getSelectedNote()
}
public func isEditable(note: Note) -> Bool {
if note.container == .encryptedTextPack { return false }
guard let editor = editorViewController?.vcEditor else { return false }
if editor.isPreviewEnabled() {
return false
}
return true
}
public func getVC() -> EditorViewController {
return self.window?.contentViewController as! EditorViewController
}
public func getEVC() -> EditorViewController? {
return self.window?.contentViewController as? EditorViewController
}
public func save() {
guard let note = self.note else { return }
note.save(attributed: self.attributedString())
}
func fill(note: Note, highlight: Bool = false, force: Bool = false) {
isScrollPositionSaverLocked = true
if !note.isLoaded {
note.load()
}
viewDelegate?.updateCounters(note: note)
textStorage?.setAttributedString(NSAttributedString(string: ""))
// Hack for invalidate prev layout data (order is important, only before fill)
if let length = textStorage?.length {
textStorage?.layoutManagers.first?.invalidateDisplay(forGlyphRange: NSRange(location: 0, length: length))
invalidateLayout()
}
undoManager?.removeAllActions(withTarget: self)
registerHandoff(note: note)
// resets timer if editor refilled
viewDelegate?.breakUndoTimer.invalidate()
unregisterDraggedTypes()
registerForDraggedTypes([
NSPasteboard.note,
NSPasteboard.PasteboardType.fileURL,
NSPasteboard.PasteboardType.URL,
NSPasteboard.PasteboardType.string
])
if let label = editorViewController?.vcNonSelectedLabel {
label.isHidden = true
if note.container == .encryptedTextPack {
label.stringValue = NSLocalizedString("Locked", comment: "")
label.isHidden = false
} else {
label.stringValue = NSLocalizedString("None Selected", comment: "")
label.isHidden = true
}
}
self.note = note
UserDefaultsManagement.lastSelectedURL = note.url
editorViewController?.updateTitle(note: note)
isEditable = isEditable(note: note)
editorViewController?.editorUndoManager = note.undoManager
typingAttributes.removeAll()
typingAttributes[.font] = UserDefaultsManagement.noteFont
if isPreviewEnabled() {
loadMarkdownWebView(note: note, force: force)
return
}
markdownView?.removeFromSuperview()
markdownView = nil
guard let storage = textStorage else { return }
if note.isMarkdown(), let content = note.content.mutableCopy() as? NSMutableAttributedString {
textStorageProcessor?.detector = CodeBlockDetector()
storage.setAttributedString(content)
} else {
storage.setAttributedString(note.content)
}
if highlight {
textStorage?.highlightKeyword(search: getSearchText())
}
viewDelegate?.restoreScrollPosition()
}
private func loadMarkdownWebView(note: Note, force: Bool) {
self.note = nil
textStorage?.setAttributedString(NSAttributedString())
self.note = note
guard let scrollView = editorViewController?.vcEditorScrollView else { return }
if markdownView == nil {
let frame = scrollView.bounds
let containerView = MPreviewContainerView(frame: frame, note: note, closure: { [weak self] in
if let point = self?.note?.contentOffsetWeb {
self?.markdownView?.restoreScrollPosition(point)
}
})
markdownView = containerView
containerView.webView.setEditorVC(evc: editorViewController)
if self.note == note {
scrollView.addSubview(containerView)
}
} else {
/// Resize markdownView
let frame = scrollView.bounds
markdownView?.frame = frame
/// Load note if needed
markdownView?.webView.load(note: note, force: force)
}
}
public func lockEncryptedView() {
textStorage?.setAttributedString(NSAttributedString())
markdownView?.removeFromSuperview()
markdownView = nil
isEditable = false
if let label = editorViewController?.vcNonSelectedLabel {
label.stringValue = NSLocalizedString("Locked", comment: "")
label.isHidden = false
}
}
public func clear() {
textStorage?.setAttributedString(NSAttributedString())
markdownView?.removeFromSuperview()
markdownView = nil
isEditable = false
window?.title = AppDelegate.appTitle
if let label = editorViewController?.vcNonSelectedLabel {
label.stringValue = NSLocalizedString("None Selected", comment: "")
label.isHidden = false
editorViewController?.dropTitle()
}
self.note = nil
if let vc = viewDelegate {
vc.updateCounters()
}
}
@IBAction func boldMenu(_ sender: Any) {
guard let note = self.note, isEditable else { return }
let formatter = TextFormatter(textView: self, note: note)
formatter.bold()
}
@IBAction func italicMenu(_ sender: Any) {
guard let note = self.note, isEditable else { return }
let formatter = TextFormatter(textView: self, note: note)
formatter.italic()
}
@IBAction func linkMenu(_ sender: Any) {
guard let note = self.note, isEditable else { return }
let formatter = TextFormatter(textView: self, note: note)
formatter.link()
}
@IBAction func underlineMenu(_ sender: Any) {
guard let note = self.note, isEditable else { return }
let formatter = TextFormatter(textView: self, note: note)
formatter.underline()
}
@IBAction func strikeMenu(_ sender: Any) {
guard let note = self.note, isEditable else { return }
let formatter = TextFormatter(textView: self, note: note)
formatter.strike()
}
@IBAction func headerMenu(_ sender: NSMenuItem) {
guard let note = self.note, isEditable else { return }
guard let id = sender.identifier?.rawValue else { return }
let code =
Int(id.replacingOccurrences(of: "format.h", with: ""))
var string = String()
for index in [1, 2, 3, 4, 5, 6] {
string = string + "#"
if code == index {
break
}
}
let formatter = TextFormatter(textView: self, note: note)
formatter.header(string)
}
@IBAction func moveSelectedLinesDown(_ sender: NSMenuItem) {
self.moveSelectedLinesDown()
}
@IBAction func moveSelectedLinesUp(_ sender: NSMenuItem) {
self.moveSelectedLinesUp()
}
@IBAction func clearCompletedTodos(_ sender: NSMenuItem) {
self.clearCompletedTodos()
}
func getParagraphRange() -> NSRange? {
guard let storage = textStorage else { return nil }
let range = selectedRange()
return storage.mutableString.paragraphRange(for: range)
}
// Clickable links flag changed with cmd / shift
override func flagsChanged(with event: NSEvent) {
super.flagsChanged(with: event)
if let mouseEvent = NSApp.currentEvent {
updateCursorForMouse(at: mouseEvent)
}
}
private func updateCursorForMouse(at event: NSEvent) {
guard let container = self.textContainer,
let manager = self.layoutManager,
let textStorage = self.textStorage else { return }
let pointInView = self.convert(event.locationInWindow, from: nil)
let pointInContainer = NSPoint(
x: pointInView.x - textContainerInset.width,
y: (self.bounds.size.height - pointInView.y) - textContainerInset.height
)
let index = manager.characterIndex(
for: pointInContainer,
in: container,
fractionOfDistanceBetweenInsertionPoints: nil
)
guard index < textStorage.length else {
NSCursor.iBeam.set()
return
}
if let link = textStorage.attribute(.link, at: index, effectiveRange: nil) {
if textStorage.attribute(.tag, at: index, effectiveRange: nil) != nil {
NSCursor.pointingHand.set()
} else if link as? URL != nil {
if UserDefaultsManagement.clickableLinks
|| NSEvent.modifierFlags.contains(.command)
|| NSEvent.modifierFlags.contains(.shift) {
NSCursor.pointingHand.set()
} else {
NSCursor.iBeam.set()
}
}
} else {
NSCursor.iBeam.set()
}
}
override func keyDown(with event: NSEvent) {
defer {
saveSelectedRange()
}
// fixes backtick marked text
if let characters = event.characters, characters == "`" {
super.insertText("`", replacementRange: selectedRange())
return
}
guard !(
event.modifierFlags.contains(.shift) &&
[
kVK_UpArrow,
kVK_DownArrow,
kVK_LeftArrow,
kVK_RightArrow
].contains(Int(event.keyCode))
) else {
super.keyDown(with: event)
return
}
guard let note = self.note else { return }
// Handle autoclose brackets
if UserDefaultsManagement.autocloseBrackets,
handleAutocloseBrackets(for: event) {
return
}
// hasMarkedText added for Japanese hack https://yllan.org/blog/archives/231
if event.keyCode == kVK_Tab && !hasMarkedText(){
breakUndoCoalescing()
let formatter = TextFormatter(textView: self, note: note)
if formatter.isListParagraph() {
if NSEvent.modifierFlags.contains(.shift) {
formatter.unTab()
} else {
formatter.tab()
}
breakUndoCoalescing()
return
}
if UserDefaultsManagement.indentUsing == 0x01 {
let tab = TextFormatter.getAttributedCode(string: " ")
insertText(tab, replacementRange: selectedRange())
breakUndoCoalescing()
return
}
if UserDefaultsManagement.indentUsing == 0x02 {
let tab = TextFormatter.getAttributedCode(string: " ")
insertText(tab, replacementRange: selectedRange())
breakUndoCoalescing()
return
}
super.keyDown(with: event)
return
}
if event.keyCode == kVK_Return && !hasMarkedText() && isEditable {
breakUndoCoalescing()
let formatter = TextFormatter(textView: self, note: note)
formatter.newLine()
breakUndoCoalescing()
return
}
if event.characters?.unicodeScalars.first == "o" && event.modifierFlags.contains(.command) {
guard let storage = textStorage else { return }
var location = selectedRange().location
if location == storage.length && location > 0 {
location = location - 1
}
if storage.length > location, let link = textStorage?.attribute(.link, at: location, effectiveRange: nil) as? String {
if link.isValidEmail(), let mail = URL(string: "mailto:\(link)") {
NSWorkspace.shared.open(mail)
} else if let url = URL(string: link) {
_ = try? NSWorkspace.shared.open(url, options: .default, configuration: [:])
}
}
return
}
super.keyDown(with: event)
}
// MARK: - Autoclose Brackets
private func handleAutocloseBrackets(for event: NSEvent) -> Bool {
let brackets: [String: String] = [
"(" : ")",
"[" : "]",
"{" : "}",
"\"" : "\""
]
guard let character = event.characters else {
return false
}
// Check if user is typing a closing bracket
let closingBrackets = Array(brackets.values)
if closingBrackets.contains(character) {
// Check if the next character is the same closing bracket
let currentRange = selectedRange()
if currentRange.length == 0,
let storage = textStorage,
currentRange.location < storage.length {
let nextCharRange = NSRange(location: currentRange.location, length: 1)
let nextCharString = storage.attributedSubstring(from: nextCharRange).string
if nextCharString == character {
// Skip the closing bracket and move cursor forward
setSelectedRange(NSMakeRange(currentRange.location + 1, 0))
return true
}
}
}
// Handle opening brackets
guard let closingBracket = brackets[character] else {
return false
}
if selectedRange().length > 0 {
// Wrap selection with brackets
let before = NSMakeRange(selectedRange().lowerBound, 0)
self.insertText(character, replacementRange: before)
let after = NSMakeRange(selectedRange().upperBound, 0)
self.insertText(closingBracket, replacementRange: after)
} else {
// Insert bracket pair
super.keyDown(with: event)
self.insertText(closingBracket, replacementRange: selectedRange())
self.moveBackward(self)
}
return true
}
override func shouldChangeText(in range: NSRange, replacementString: String?) -> Bool {
guard let note = self.note else {
return super.shouldChangeText(in: range, replacementString: replacementString)
}
note.resetAttributesCache()
scheduleTagScan(for: note)
deleteUnusedImages(checkRange: range)
resetTypingAttributes()
return super.shouldChangeText(in: range, replacementString: replacementString)
}
// MARK: Autocomplete overrides
var suppressCompletion = false
public var forceSystemAutocomplete = false
private var isSystemCompletionSession = false
override func didChangeText() {
super.didChangeText()
if suppressCompletion {
suppressCompletion = false
return
}
if detectCompletionContext() != .none {
complete(nil)
}
}
override func completions(forPartialWordRange charRange: NSRange,
indexOfSelectedItem index: UnsafeMutablePointer) -> [String]? {
if forceSystemAutocomplete {
isSystemCompletionSession = true
forceSystemAutocomplete = false
return super.completions(forPartialWordRange: charRange, indexOfSelectedItem: index)
}
return handleCompletions(index: index)
}
override func insertCompletion(_ word: String,
forPartialWordRange charRange: NSRange,
movement: Int,
isFinal flag: Bool) {
if isSystemCompletionSession {
super.insertCompletion(word, forPartialWordRange: charRange, movement: movement, isFinal: flag)
if flag {
isSystemCompletionSession = false
}
return
}
handleInsertCompletion(word: word, movement: movement, isFinal: flag)
}
override var rangeForUserCompletion: NSRange {
if isSystemCompletionSession {
return super.rangeForUserCompletion
}
return calculateCompletionRange()
}
@objc public func scanTagsAndAutoRename() {
guard let vc = ViewController.shared() else { return }
let notes = vc.tagsScannerQueue
attributesCachingQueue.addOperation {
for note in notes {
note.cache()
}
}
for note in notes {
let result = note.scanContentTags()
guard let outline = ViewController.shared()?.sidebarOutlineView else { return }
let added = result.0
let removed = result.1
if removed.count > 0 {
outline.removeTags(removed)
}
if added.count > 0 {
outline.addTags(added)
}
if let title = note.getAutoRenameTitle() {
note.rename(to: title)
if let editorViewController = getEVC() {
editorViewController.vcTitleLabel?.updateNotesTableView()
editorViewController.updateTitle(note: note)
}
}
ViewController.shared()?.tagsScannerQueue.removeAll(where: { $0 === note })
}
}
func saveSelectedRange() {
guard let note = self.note else { return }
note.setSelectedRange(range: selectedRange)
}
func loadSelectedRange() {
guard let storage = textStorage else { return }
if let range = self.note?.getSelectedRange(), range.upperBound <= storage.length {
setSelectedRange(range)
scrollToCursor()
}
}
func setEditorTextColor(_ color: NSColor) {
if let note = self.note, !note.isMarkdown() {
textColor = color
}
}
override func awakeFromNib() {
super.awakeFromNib()
imagesLoaderQueue.maxConcurrentOperationCount = 3
imagesLoaderQueue.qualityOfService = .userInteractive
}
override var textContainerOrigin: NSPoint {
let origin = super.textContainerOrigin
return NSPoint(x: origin.x, y: origin.y - 7)
}
override func performDragOperation(_ sender: NSDraggingInfo) -> Bool {
guard let note = self.note, let storage = textStorage else { return false }
let pasteboard = sender.draggingPasteboard
let dropPoint = convert(sender.draggingLocation, from: nil)
let caretLocation = characterIndexForInsertion(at: dropPoint)
let replacementRange = NSRange(location: caretLocation, length: 0)
if handleAttributedText(pasteboard, note: note, storage: storage, replacementRange: replacementRange) { return true }
if handleNoteReference(pasteboard, note: note, replacementRange: replacementRange) { return true }
if handleURLs(pasteboard, note: note, replacementRange: replacementRange) { return true }
return super.performDragOperation(sender)
}
func fetchDataFromURL(url: URL, completion: @escaping (Data?, Error?) -> Void) {
let session = URLSession.shared
let task = session.dataTask(with: url) { (data, response, error) in
if let error = error {
completion(nil, error)
return
}
completion(data, nil)
}
task.resume()
}
func getHTMLTitle(from data: Data) -> String? {
guard let htmlString = String(data: data, encoding: .utf8) else {
return nil
}
return extractTitle(from: htmlString)
}
func getSearchText() -> String {
guard let search = ViewController.shared()?.search else { return String() }
if let editor = search.currentEditor(), editor.selectedRange.length > 0 {
return (search.stringValue as NSString).substring(with: NSRange(0.. Bool {
if let fr = self.window?.firstResponder, fr.isKind(of: EditTextView.self) {
return true
}
return false
}
@IBAction func shiftLeft(_ sender: Any) {
guard let note = self.note, isEditable else { return }
let f = TextFormatter(textView: self, note: note)
f.unTab()
}
@IBAction func shiftRight(_ sender: Any) {
guard let note = self.note, isEditable else { return }
let f = TextFormatter(textView: self, note: note)
f.tab()
}
@IBAction func todo(_ sender: Any) {
guard let f = self.getTextFormatter(), isEditable else { return }
f.todo()
}
@IBAction func wikiLinks(_ sender: Any) {
guard let note = self.note, isEditable else { return }
let formatter = TextFormatter(textView: self, note: note)
formatter.wikiLink()
}
@IBAction func pressBold(_ sender: Any) {
guard let note = self.note, isEditable else { return }
let formatter = TextFormatter(textView: self, note: note)
formatter.bold()
}
@IBAction func pressItalic(_ sender: Any) {
guard let note = self.note, isEditable else { return }
let formatter = TextFormatter(textView: self, note: note)
formatter.italic()
}
@IBAction func insertFileOrImage(_ sender: Any) {
guard let note = self.note, isEditable else { return }
let panel = NSOpenPanel()
panel.allowsMultipleSelection = true
panel.canChooseDirectories = false
panel.canChooseFiles = true
panel.canCreateDirectories = true
panel.begin { (result) -> Void in
if result == NSApplication.ModalResponse.OK {
let urls = panel.urls
for url in urls {
if self.saveFile(url: url, in: note) {
if urls.count > 1 {
self.insertNewline(nil)
}
}
}
if let vc = ViewController.shared() {
vc.notesTableView.reloadRow(note: note)
}
}
}
}
@IBAction func insertCodeBlock(_ sender: NSButton) {
guard isEditable else { return }
let currentRange = selectedRange()
if currentRange.length > 0 {
let mutable = NSMutableAttributedString(string: "```\n")
if let substring = attributedSubstring(forProposedRange: currentRange, actualRange: nil) {
mutable.append(substring)
if substring.string.last != "\n" {
mutable.append(NSAttributedString(string: "\n"))
}
}
mutable.append(NSAttributedString(string: "```\n"))
insertText(mutable, replacementRange: currentRange)
setSelectedRange(NSRange(location: currentRange.location + 3, length: 0))
return
}
insertText("```\n\n```\n", replacementRange: currentRange)
setSelectedRange(NSRange(location: currentRange.location + 3, length: 0))
}
@IBAction func insertCodeSpan(_ sender: NSMenuItem) {
guard isEditable else { return }
let currentRange = selectedRange()
if currentRange.length > 0 {
let mutable = NSMutableAttributedString(string: "`")
if let substring = attributedSubstring(forProposedRange: currentRange, actualRange: nil) {
mutable.append(substring)
}
mutable.append(NSAttributedString(string: "`"))
insertText(mutable, replacementRange: currentRange)
return
}
insertText("``", replacementRange: currentRange)
setSelectedRange(NSRange(location: currentRange.location + 1, length: 0))
}
@IBAction func insertList(_ sender: NSMenuItem) {
guard let note = self.note, isEditable else { return }
let formatter = TextFormatter(textView: self, note: note)
formatter.list()
}
@IBAction func insertOrderedList(_ sender: NSMenuItem) {
guard let note = self.note, isEditable else { return }
let formatter = TextFormatter(textView: self, note: note)
formatter.orderedList()
}
@IBAction func insertQuote(_ sender: NSMenuItem) {
guard let note = self.note, isEditable else { return }
let formatter = TextFormatter(textView: self, note: note)
formatter.quote()
}
@IBAction func insertLink(_ sender: Any) {
guard let note = self.note, isEditable else { return }
let formatter = TextFormatter(textView: self, note: note)
formatter.link()
}
private func getTextFormatter() -> TextFormatter? {
guard let note = self.note, isEditable else { return nil }
return TextFormatter(textView: self, note: note)
}
override func prepareForDragOperation(_ sender: NSDraggingInfo) -> Bool {
return true
}
override func draggingUpdated(_ sender: NSDraggingInfo) -> NSDragOperation {
if sender.draggingPasteboard.data(forType: NSPasteboard.note) != nil {
let dropPoint = convert(sender.draggingLocation, from: nil)
let caretLocation = characterIndexForInsertion(at: dropPoint)
setSelectedRange(NSRange(location: caretLocation, length: 0))
return .copy
}
return super.draggingUpdated(sender)
}
override func clicked(onLink link: Any, at charIndex: Int) {
if handleEmailLink(link) { return }
if handleAnchorLink(link) { return }
if !isAttachmentAtPosition(charIndex) {
if handleRegularLink(link, at: charIndex) { return }
}
}
override func viewDidChangeEffectiveAppearance() {
UserDataService.instance.isDark = effectiveAppearance.isDark
storage.resetCacheAttributes()
// clear preview cache
MPreviewView.template = nil
let webkitPreview = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("wkPreview")
try? FileManager.default.removeItem(at: webkitPreview)
NotesTextProcessor.hl = nil
guard let note = self.note else { return }
NotesTextProcessor.highlight(attributedString: note.content)
let funcName = effectiveAppearance.isDark ? "switchToDarkMode" : "switchToLightMode"
let switchScript = "if (typeof(\(funcName)) == 'function') { \(funcName)(); }"
downView?.evaluateJavaScript(switchScript)
viewDelegate?.refillEditArea(force: true)
}
private func saveFile(url: URL, in note: Note) -> Bool {
if let data = try? Data(contentsOf: url) {
let preferredName = url.lastPathComponent
guard let attributed = NSMutableAttributedString.build(data: data, preferredName: preferredName) else { return false }
breakUndoCoalescing()
insertText(attributed, replacementRange: selectedRange())
breakUndoCoalescing()
return true
}
return false
}
public func updateTextContainerInset() {
textContainerInset.width = getInsetWidth()
}
public func getInsetWidth() -> CGFloat {
let lineWidth = UserDefaultsManagement.lineWidth
let margin = UserDefaultsManagement.marginSize
let width = frame.width
if lineWidth == 1000 {
return CGFloat(margin)
}
guard Float(width) - margin * 2 > lineWidth else {
return CGFloat(margin)
}
return CGFloat((Float(width) - lineWidth) / 2)
}
private func deleteUnusedImages(checkRange: NSRange) {
guard let storage = textStorage, self.note != nil else { return }
storage.enumerateAttribute(.attachment, in: checkRange) { (value, range, _) in
guard let meta = storage.getMeta(at: range.location) else { return }
do {
if let data = try? Data(contentsOf: meta.url) {
storage.addAttribute(.attachmentSave, value: data, range: range)
try FileManager.default.removeItem(at: meta.url)
}
} catch {
print(error)
}
}
}
@available(OSX 10.12.2, *)
override func makeTouchBar() -> NSTouchBar? {
let touchBar = NSTouchBar()
touchBar.delegate = self
touchBar.defaultItemIdentifiers = [
NSTouchBarItem.Identifier("Todo"),
NSTouchBarItem.Identifier("Bold"),
NSTouchBarItem.Identifier("Italic"),
.fixedSpaceSmall,
NSTouchBarItem.Identifier("Link"),
NSTouchBarItem.Identifier("Image or file"),
NSTouchBarItem.Identifier("CodeBlock"),
.fixedSpaceSmall,
NSTouchBarItem.Identifier("Indent"),
NSTouchBarItem.Identifier("UnIndent")
]
return touchBar
}
@available(OSX 10.12.2, *)
override func touchBar(_ touchBar: NSTouchBar, makeItemForIdentifier identifier: NSTouchBarItem.Identifier) -> NSTouchBarItem? {
switch identifier {
case NSTouchBarItem.Identifier("Todo"):
if let im = NSImage(named: "todo"), im.isValid, im.size.height > 0 {
let image = im.tint(color: NSColor.white)
image.size = NSSize(width: 20, height: 20)
let button = NSButton(image: image, target: self, action: #selector(todo(_:)))
button.bezelColor = NSColor(red:0.21, green:0.21, blue:0.21, alpha:1.0)
let customViewItem = NSCustomTouchBarItem(identifier: identifier)
customViewItem.view = button
return customViewItem
}
case NSTouchBarItem.Identifier("Bold"):
if let im = NSImage(named: "bold"), im.isValid, im.size.height > 0 {
let image = im.tint(color: NSColor.white)
image.size = NSSize(width: 20, height: 20)
let button = NSButton(image: image, target: self, action: #selector(pressBold(_:)))
button.bezelColor = NSColor(red:0.21, green:0.21, blue:0.21, alpha:1.0)
let customViewItem = NSCustomTouchBarItem(identifier: identifier)
customViewItem.view = button
return customViewItem
}
case NSTouchBarItem.Identifier("Italic"):
if let im = NSImage(named: "italic"), im.isValid, im.size.height > 0 {
let image = im.tint(color: NSColor.white)
image.size = NSSize(width: 20, height: 20)
let button = NSButton(image: image, target: self, action: #selector(pressItalic(_:)))
button.bezelColor = NSColor(red:0.21, green:0.21, blue:0.21, alpha:1.0)
let customViewItem = NSCustomTouchBarItem(identifier: identifier)
customViewItem.view = button
return customViewItem
}
case NSTouchBarItem.Identifier("Image or file"):
if let im = NSImage(named: "image"), im.isValid, im.size.height > 0 {
let image = im.tint(color: NSColor.white)
image.size = NSSize(width: 20, height: 20)
let button = NSButton(image: image, target: self, action: #selector(insertFileOrImage(_:)))
button.bezelColor = NSColor(red:0.21, green:0.21, blue:0.21, alpha:1.0)
let customViewItem = NSCustomTouchBarItem(identifier: identifier)
customViewItem.view = button
return customViewItem
}
case NSTouchBarItem.Identifier("Indent"):
if let im = NSImage(named: "indent"), im.isValid, im.size.height > 0 {
let image = im.tint(color: NSColor.white)
image.size = NSSize(width: 20, height: 20)
let button = NSButton(image: image, target: self, action: #selector(shiftRight(_:)))
button.bezelColor = NSColor(red:0.21, green:0.21, blue:0.21, alpha:1.0)
let customViewItem = NSCustomTouchBarItem(identifier: identifier)
customViewItem.view = button
return customViewItem
}
case NSTouchBarItem.Identifier("UnIndent"):
if let im = NSImage(named: "unindent"), im.isValid, im.size.height > 0 {
let image = im.tint(color: NSColor.white)
image.size = NSSize(width: 20, height: 20)
let button = NSButton(image: image, target: self, action: #selector(shiftLeft(_:)))
button.bezelColor = NSColor(red:0.21, green:0.21, blue:0.21, alpha:1.0)
let customViewItem = NSCustomTouchBarItem(identifier: identifier)
customViewItem.view = button
return customViewItem
}
case NSTouchBarItem.Identifier("CodeBlock"):
if let im = NSImage(named: "codeblock"), im.isValid, im.size.height > 0 {
let image = im.tint(color: NSColor.white)
image.size = NSSize(width: 20, height: 20)
let button = NSButton(image: image, target: self, action: #selector(insertCodeBlock(_:)))
button.bezelColor = NSColor(red:0.21, green:0.21, blue:0.21, alpha:1.0)
let customViewItem = NSCustomTouchBarItem(identifier: identifier)
customViewItem.view = button
return customViewItem
}
case NSTouchBarItem.Identifier("Link"):
if let im = NSImage(named: "tb_link"), im.isValid, im.size.height > 0 {
let image = im.tint(color: NSColor.white)
image.size = NSSize(width: 20, height: 20)
let button = NSButton(image: image, target: self, action: #selector(insertLink(_:)))
button.bezelColor = NSColor(red:0.21, green:0.21, blue:0.21, alpha:1.0)
let customViewItem = NSCustomTouchBarItem(identifier: identifier)
customViewItem.view = button
return customViewItem
}
default: break
}
return super.touchBar(touchBar, makeItemForIdentifier: identifier)
}
override func menu(for event: NSEvent) -> NSMenu? {
let menu = super.menu(for: event)
let editTitle = NSLocalizedString("Edit Link…", comment: "")
if let editLink = menu?.item(withTitle: editTitle) {
menu?.removeItem(editLink)
}
let removeTitle = NSLocalizedString("Remove Link", comment: "")
if let removeLink = menu?.item(withTitle: removeTitle) {
menu?.removeItem(removeLink)
}
return menu
}
/**
Handoff methods
*/
override func updateUserActivityState(_ userActivity: NSUserActivity) {
guard let note = self.note else { return }
let position =
window?.firstResponder == self ? selectedRange().location : -1
let state = editorViewController?.vcEditor?.preview == true ? "preview" : "editor"
let data =
[
"note-file-name": note.name,
"position": String(position),
"state": state
]
userActivity.addUserInfoEntries(from: data)
}
override func resignFirstResponder() -> Bool {
userActivity?.needsSave = true
return super.resignFirstResponder()
}
public func registerHandoff(note: Note) {
self.userActivity?.invalidate()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
let updateDict: [String: String] = ["note-file-name": note.name]
let activity = NSUserActivity(activityType: "es.fsnot.handoff-open-note")
activity.isEligibleForHandoff = true
activity.userInfo = updateDict
activity.title = NSLocalizedString("Open note", comment: "Document opened")
self.userActivity = activity
self.userActivity?.becomeCurrent()
}
}
public func changePreviewState(_ state: Bool) {
preview = state
}
public func togglePreviewState() {
self.preview = !self.preview
note?.previewState = self.preview
}
public func isPreviewEnabled() -> Bool {
return preview
}
public func disablePreviewEditorAndNote() {
preview = false
note?.previewState = false
}
public func scheduleTagScan(for note: Note) {
if let vc = ViewController.shared(),
!vc.tagsScannerQueue.contains(note) {
vc.tagsScannerQueue.append(note)
}
tagsTimer?.invalidate()
tagsTimer = Timer.scheduledTimer(
timeInterval: 2.5,
target: self,
selector: #selector(scanTagsAndAutoRename),
userInfo: nil,
repeats: false
)
}
public func resetTypingAttributes() {
typingAttributes.removeValue(forKey: .attachmentUrl)
typingAttributes.removeValue(forKey: .attachmentTitle)
typingAttributes.removeValue(forKey: .attachmentPath)
typingAttributes.removeValue(forKey: .attachmentSave)
typingAttributes.removeValue(forKey: .todo)
typingAttributes.removeValue(forKey: .tag)
if let style = typingAttributes[.paragraphStyle] as? NSMutableParagraphStyle {
style.alignment = .left
}
typingAttributes[.font] = UserDefaultsManagement.noteFont
}
}
================================================
FILE: FSNotes/View/EditorScrollView.swift
================================================
//
// EditorScrollView.swift
// FSNotes
//
// Created by Oleksandr Glushchenko on 10/7/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
class EditorScrollView: NSScrollView {
private var initialHeight: CGFloat?
override var isFindBarVisible: Bool {
set {
// macOS 10.14 margin hack
if #available(OSX 10.14, *) {
if let clip = self.subviews.first as? NSClipView {
clip.contentInsets.top = newValue ? 60 : 10
if newValue, let documentView = self.documentView {
documentView.scroll(NSPoint(x: 0, y: -60))
}
}
}
super.isFindBarVisible = newValue
}
get {
return super.isFindBarVisible
}
}
//
//
// override func findBarViewDidChangeHeight() {
// if #available(OSX 10.14, *) {
// guard let currentHeight = findBarView?.frame.height else { return }
//
// guard let initialHeight = self.initialHeight else {
// self.initialHeight = currentHeight
// return
// }
//
// if let clip = self.subviews.first as? NSClipView {
// let margin = currentHeight > initialHeight ? 65 : 40
// clip.contentInsets.top = CGFloat(margin)
//
// if let documentView = self.documentView {
// documentView.scroll(NSPoint(x: 0, y: -margin))
// }
// }
// } else {
// super.findBarViewDidChangeHeight()
// }
// }
}
================================================
FILE: FSNotes/View/EditorSplitView.swift
================================================
//
// EditorSplitView.swift
// FSNotes
//
// Created by Oleksandr Glushchenko on 4/20/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
class EditorSplitView: NSSplitView, NSSplitViewDelegate {
public var shouldHideDivider = false
override func draw(_ dirtyRect: NSRect) {
self.delegate = self
super.draw(dirtyRect)
}
override func minPossiblePositionOfDivider(at dividerIndex: Int) -> CGFloat {
return 0
}
/*
func splitView(_ splitView: NSSplitView, constrainMinCoordinate proposedMinimumPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat {
return (shouldHideDivider || UserDefaultsManagement.horizontalOrientation) ? 0 : 200
}
func splitView(_ splitView: NSSplitView, constrainMaxCoordinate proposedMaximumPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat {
return UserDefaultsManagement.horizontalOrientation ? 99999 : 350
}*/
override var dividerColor: NSColor {
return NSColor.init(named: "divider")!
}
override var dividerThickness: CGFloat {
get {
return shouldHideDivider ? 0 : 1
}
}
func splitViewDidResizeSubviews(_ notification: Notification) {
ViewController.shared()?.viewDidResize()
}
func splitViewWillResizeSubviews(_ notification: Notification) {
if let vc = ViewController.shared() {
vc.editor.updateTextContainerInset()
}
}
}
================================================
FILE: FSNotes/View/EditorView.swift
================================================
//
// EditorView.swift
// FSNotes
//
// Created by Oleksandr Glushchenko on 9/29/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
class EditorView: NSView {
override func mouseDown(with event: NSEvent) {
guard let vc = ViewController.shared() else { return }
vc.editor.mouseDown(with: event)
NSApp.mainWindow?.makeFirstResponder(vc.editor)
}
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
NSColor(named: "mainBackground")!.setFill()
__NSRectFill(dirtyRect)
}
}
================================================
FILE: FSNotes/View/HyperlinkTextField.swift
================================================
//
// HyperlinkTextField.swift
// FSNotes
//
// Created by Oleksandr Hlushchenko on 13.11.2022.
// Copyright © 2022 Oleksandr Hlushchenko. All rights reserved.
//
import Cocoa
@IBDesignable
class HyperlinkTextField: NSTextField {
@IBInspectable var href: String = ""
override func awakeFromNib() {
super.awakeFromNib()
let attributes: [NSAttributedString.Key : Any] = [
NSAttributedString.Key.foregroundColor: NSColor.blue,
NSAttributedString.Key.underlineStyle: NSUnderlineStyle.single.rawValue
]
self.attributedStringValue = NSAttributedString(string: self.stringValue, attributes: attributes)
}
override func mouseDown(with event: NSEvent) {
NSWorkspace.shared.open(URL(string: self.href)!)
}
}
================================================
FILE: FSNotes/View/MPreviewContainerView.swift
================================================
//
// MPreviewContainerView.swift
// FSNotes
//
// Created by Oleksandr Hlushchenko on 21.12.2025.
// Copyright © 2025 Oleksandr Hlushchenko. All rights reserved.
//
import AppKit
class MPreviewContainerView: NSView {
// UI Elements
public var webView: MPreviewView!
private var findPanel: MPreviewFindPanel!
private var findPanelHeightConstraint: NSLayoutConstraint!
// Search state
private var currentMatchIndex = 0
private var totalMatches = 0
public var isFindPanelVisible = false
// MARK: - Initialization
init(frame: NSRect, note: Note, closure: MPreviewViewClosure?, force: Bool = false) {
super.init(frame: frame)
setupWebView(note: note, closure: closure, force: force)
setupFindPanel()
setupLayout()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
private func setupLayout() {
NSLayoutConstraint.activate([
webView.leadingAnchor.constraint(equalTo: leadingAnchor),
webView.trailingAnchor.constraint(equalTo: trailingAnchor),
webView.topAnchor.constraint(equalTo: findPanel.bottomAnchor),
webView.bottomAnchor.constraint(equalTo: bottomAnchor)
])
}
private func setupWebView(note: Note, closure: MPreviewViewClosure?, force: Bool) {
webView = MPreviewView(frame: bounds, note: note, closure: closure, force: force)
webView.translatesAutoresizingMaskIntoConstraints = false
addSubview(webView)
}
private func setupFindPanel() {
findPanel = MPreviewFindPanel()
findPanel.translatesAutoresizingMaskIntoConstraints = false
addSubview(findPanel)
NSLayoutConstraint.activate([
findPanel.leadingAnchor.constraint(equalTo: leadingAnchor),
findPanel.trailingAnchor.constraint(equalTo: trailingAnchor),
findPanel.topAnchor.constraint(equalTo: topAnchor)
])
findPanel.isHidden = true
findPanel.panelHeightConstraint.constant = 0
// Callbacks
findPanel.onSearch = { [weak self] searchText in
self?.performSearch(searchText)
}
findPanel.onNext = { [weak self] in
self?.findNext()
}
findPanel.onPrevious = { [weak self] in
self?.findPrevious()
}
findPanel.onDone = { [weak self] in
self?.hideFindPanel()
}
}
// MARK: - Public API
var previewView: MPreviewView {
return webView
}
func showFindPanel() {
window?.makeFirstResponder(self)
isFindPanelVisible = true
let pasteboard = NSPasteboard(name: .find)
if let searchText = pasteboard.string(forType: .string) {
pasteboard.clearContents()
findPanel.searchField.stringValue = searchText
findPanel.onSearch?(searchText)
}
findPanel.show()
}
func hideFindPanel() {
isFindPanelVisible = false
findPanel.hide()
clearHighlights()
}
func toggleFindPanel() {
if isFindPanelVisible {
hideFindPanel()
} else {
showFindPanel()
}
}
// MARK: - Search Implementation
private func performSearch(_ searchText: String) {
guard !searchText.isEmpty else {
clearHighlights()
return
}
let escapedText = searchText
.replacingOccurrences(of: "\\", with: "\\\\")
.replacingOccurrences(of: "'", with: "\\'")
.replacingOccurrences(of: "\"", with: "\\\"")
let jsCode = """
(function() {
document.querySelectorAll('.mpreview-find-highlight').forEach(el => {
var parent = el.parentNode;
parent.replaceChild(document.createTextNode(el.textContent), el);
parent.normalize();
});
var searchText = '\(escapedText)';
if (searchText.length === 0) return 0;
var escapedSearch = searchText.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');
var regex = new RegExp('(' + escapedSearch + ')', 'gi');
var walker = document.createTreeWalker(
document.body,
NodeFilter.SHOW_TEXT,
{
acceptNode: function(node) {
if (node.parentNode.nodeName === 'SCRIPT' ||
node.parentNode.nodeName === 'STYLE' ||
node.parentNode.classList.contains('mpreview-find-highlight')) {
return NodeFilter.FILTER_REJECT;
}
return NodeFilter.FILTER_ACCEPT;
}
},
false
);
var nodesToReplace = [];
while(walker.nextNode()) {
var node = walker.currentNode;
if(regex.test(node.textContent)) {
nodesToReplace.push(node);
}
}
var matchCount = 0;
nodesToReplace.forEach(function(node) {
var text = node.textContent;
var matches = text.match(regex);
if (!matches) return;
var fragment = document.createDocumentFragment();
var lastIndex = 0;
var tempText = text;
while(true) {
var match = regex.exec(tempText);
if (!match) break;
var index = match.index;
if (index > lastIndex) {
fragment.appendChild(document.createTextNode(tempText.substring(lastIndex, index)));
}
var mark = document.createElement('mark');
mark.className = 'mpreview-find-highlight';
mark.setAttribute('data-index', matchCount);
mark.textContent = match[0];
fragment.appendChild(mark);
matchCount++;
lastIndex = index + match[0].length;
}
if (lastIndex < text.length) {
fragment.appendChild(document.createTextNode(tempText.substring(lastIndex)));
}
node.parentNode.replaceChild(fragment, node);
});
var firstMatch = document.querySelector('.mpreview-find-highlight');
if(firstMatch) {
firstMatch.classList.add('current-match');
firstMatch.scrollIntoView({behavior: 'smooth', block: 'center'});
}
return matchCount;
})();
"""
webView.evaluateJavaScript(jsCode) { [weak self] result, error in
if error != nil {
print("Search error: \\(error)")
}
if let count = result as? Int {
self?.totalMatches = count
self?.currentMatchIndex = count > 0 ? 1 : 0
self?.findPanel.updateStatus(current: self?.currentMatchIndex ?? 0,
total: self?.totalMatches ?? 0)
}
}
injectHighlightStyles()
}
func getSelectedText(completion: @escaping (String?) -> Void) {
let javascript = "window.getSelection().toString()"
webView.evaluateJavaScript(javascript) { (result, error) in
if let error = error {
print("Error: \(error)")
completion(nil)
} else {
completion(result as? String)
}
}
}
private func injectHighlightStyles() {
let css = """
mark.mpreview-find-highlight {
background-color: rgba(255, 255, 0, 0.35);
color: inherit;
padding: 1px 0;
border-radius: 2px;
}
mark.mpreview-find-highlight.current-match {
background-color: rgba(255, 143, 0, 0.8) !important;
outline: 2px solid rgba(255, 100, 0, 0.6);
}
"""
let escapedCSS = css
.replacingOccurrences(of: "\n", with: " ")
.replacingOccurrences(of: "'", with: "\\'")
let jsCode = """
(function() {
var style = document.getElementById('mpreview-find-style');
if(!style) {
style = document.createElement('style');
style.id = 'mpreview-find-style';
document.head.appendChild(style);
}
style.innerHTML = '\(escapedCSS)';
})();
"""
webView.evaluateJavaScript(jsCode)
}
public func findNext() {
guard totalMatches > 0 else { return }
let jsCode = """
(function() {
var marks = document.querySelectorAll('.mpreview-find-highlight');
if(marks.length === 0) return 0;
var current = document.querySelector('.current-match');
if(current) {
current.classList.remove('current-match');
}
var currentIndex = current ? Array.from(marks).indexOf(current) : -1;
var nextIndex = (currentIndex + 1) % marks.length;
marks[nextIndex].classList.add('current-match');
marks[nextIndex].scrollIntoView({behavior: 'smooth', block: 'center'});
return nextIndex + 1;
})();
"""
webView.evaluateJavaScript(jsCode) { [weak self] result, error in
if let index = result as? Int {
self?.currentMatchIndex = index
self?.findPanel.updateStatus(current: index, total: self?.totalMatches ?? 0)
}
}
}
private func findPrevious() {
guard totalMatches > 0 else { return }
let jsCode = """
(function() {
var marks = document.querySelectorAll('.mpreview-find-highlight');
if(marks.length === 0) return 0;
var current = document.querySelector('.current-match');
if(current) {
current.classList.remove('current-match');
}
var currentIndex = current ? Array.from(marks).indexOf(current) : 0;
var prevIndex = currentIndex - 1;
if(prevIndex < 0) prevIndex = marks.length - 1;
marks[prevIndex].classList.add('current-match');
marks[prevIndex].scrollIntoView({behavior: 'smooth', block: 'center'});
return prevIndex + 1;
})();
"""
webView.evaluateJavaScript(jsCode) { [weak self] result, error in
if let index = result as? Int {
self?.currentMatchIndex = index
self?.findPanel.updateStatus(current: index, total: self?.totalMatches ?? 0)
}
}
}
private func clearHighlights() {
let jsCode = """
(function() {
document.querySelectorAll('.mpreview-find-highlight').forEach(el => {
var parent = el.parentNode;
parent.replaceChild(document.createTextNode(el.textContent), el);
parent.normalize();
});
})();
"""
webView.evaluateJavaScript(jsCode)
totalMatches = 0
currentMatchIndex = 0
findPanel.updateStatus(current: 0, total: 0)
}
@objc override func performTextFinderAction(_ sender: Any?) {
guard let menuItem = sender as? NSMenuItem else {
return
}
switch NSTextFinder.Action(rawValue: menuItem.tag) {
case .showFindInterface:
showFindPanel()
case .hideFindInterface:
hideFindPanel()
case .nextMatch:
findNext()
case .previousMatch:
findPrevious()
case .showReplaceInterface:
break
case .replace, .replaceAll, .replaceAndFind:
break
case .setSearchString:
getSelectedText { [weak self] text in
if let text = text, !text.isEmpty {
self?.performSearch(text)
}
}
case .selectAll, .selectAllInSelection:
break
default:
break
}
}
func getScrollPosition(_ completion: @escaping (CGPoint) -> Void) {
let js = "({ x: window.scrollX, y: window.scrollY })"
webView.evaluateJavaScript(js) { result, _ in
if let dict = result as? [String: CGFloat],
let x = dict["x"],
let y = dict["y"] {
completion(CGPoint(x: x, y: y))
} else {
completion(.zero)
}
}
}
func restoreScrollPosition(_ point: CGPoint) {
let js = "window.scrollTo(\(point.x), \(point.y));"
webView.evaluateJavaScript(js, completionHandler: nil)
}
}
================================================
FILE: FSNotes/View/MPreviewFindPanel.swift
================================================
//
// MPreviewFindPanel.swift
// FSNotes
//
// Created by Oleksandr Hlushchenko on 21.12.2025.
// Copyright © 2025 Oleksandr Hlushchenko. All rights reserved.
//
import Cocoa
import WebKit
final class MPreviewFindPanel: NSVisualEffectView, NSSearchFieldDelegate {
// MARK: UI
public let searchField = NSSearchField()
private let previousButton = NSButton()
private let nextButton = NSButton()
private let doneButton = NSButton()
private let statusLabel = NSTextField()
private let containerView = NSView()
public var panelHeightConstraint: NSLayoutConstraint!
private var containerHeightConstraint: NSLayoutConstraint!
// MARK: Callbacks
var onSearch: ((String) -> Void)?
var onNext: (() -> Void)?
var onPrevious: (() -> Void)?
var onDone: (() -> Void)?
// MARK: Init
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
setupUI()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setupUI()
}
// MARK: Setup
private func setupUI() {
material = .windowBackground
blendingMode = .behindWindow
state = .active
translatesAutoresizingMaskIntoConstraints = false
panelHeightConstraint = heightAnchor.constraint(equalToConstant: 36)
panelHeightConstraint.isActive = true
setupContainer()
setupControls()
}
private func setupContainer() {
containerView.translatesAutoresizingMaskIntoConstraints = false
addSubview(containerView)
containerHeightConstraint = containerView.heightAnchor.constraint(equalToConstant: 28)
NSLayoutConstraint.activate([
containerView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 8),
containerView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -8),
containerView.centerYAnchor.constraint(equalTo: centerYAnchor),
containerHeightConstraint
])
}
private func setupControls() {
// Search field
searchField.placeholderString = NSLocalizedString("Search", comment: "")
searchField.delegate = self
prepare(searchField)
// Buttons
configureButton(previousButton, systemImage: "chevron.up", action: #selector(previousClicked))
configureButton(nextButton, systemImage: "chevron.down", action: #selector(nextClicked))
// Status
statusLabel.isEditable = false
statusLabel.isBordered = false
statusLabel.backgroundColor = .clear
statusLabel.font = .systemFont(ofSize: 11)
statusLabel.textColor = .secondaryLabelColor
statusLabel.alignment = .center
prepare(statusLabel)
// Done
doneButton.title = NSLocalizedString("Done", comment: "")
doneButton.bezelStyle = .texturedRounded
doneButton.target = self
doneButton.action = #selector(doneClicked)
prepare(doneButton)
layoutControls()
}
private func prepare(_ view: NSView) {
view.translatesAutoresizingMaskIntoConstraints = false
containerView.addSubview(view)
}
private func configureButton(_ button: NSButton, systemImage: String, action: Selector) {
button.image = NSImage(systemSymbolName: systemImage, accessibilityDescription: nil)
button.imagePosition = .imageOnly
button.bezelStyle = .texturedRounded
button.target = self
button.action = action
prepare(button)
}
private func layoutControls() {
NSLayoutConstraint.activate([
searchField.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
searchField.centerYAnchor.constraint(equalTo: containerView.centerYAnchor),
searchField.widthAnchor.constraint(equalToConstant: 200),
previousButton.leadingAnchor.constraint(equalTo: searchField.trailingAnchor, constant: 8),
previousButton.centerYAnchor.constraint(equalTo: containerView.centerYAnchor),
previousButton.widthAnchor.constraint(equalToConstant: 32),
nextButton.leadingAnchor.constraint(equalTo: previousButton.trailingAnchor, constant: 4),
nextButton.centerYAnchor.constraint(equalTo: containerView.centerYAnchor),
nextButton.widthAnchor.constraint(equalToConstant: 32),
statusLabel.leadingAnchor.constraint(equalTo: nextButton.trailingAnchor, constant: 8),
statusLabel.centerYAnchor.constraint(equalTo: containerView.centerYAnchor),
statusLabel.widthAnchor.constraint(greaterThanOrEqualToConstant: 60),
doneButton.leadingAnchor.constraint(equalTo: statusLabel.trailingAnchor, constant: 8),
doneButton.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
doneButton.centerYAnchor.constraint(equalTo: containerView.centerYAnchor)
])
}
// MARK: Public API
func show() {
isHidden = false
NSAnimationContext.runAnimationGroup { context in
context.duration = 0.25
panelHeightConstraint.animator().constant = 36
alphaValue = 1
} completionHandler: {
self.window?.makeFirstResponder(self.searchField)
}
}
func hide() {
NSAnimationContext.runAnimationGroup { context in
context.duration = 0.25
panelHeightConstraint.animator().constant = 0
alphaValue = 0
} completionHandler: {
self.isHidden = true
}
}
func updateStatus(current: Int, total: Int) {
statusLabel.stringValue = total > 0 ? "\(current) from \(total)" : "Not found"
}
func clear() {
searchField.stringValue = ""
statusLabel.stringValue = ""
}
// MARK: Actions
@objc private func searchFieldChanged(_ sender: NSSearchField) {
onSearch?(sender.stringValue)
}
@objc private func previousClicked() {
onPrevious?()
}
@objc private func nextClicked() {
onNext?()
}
@objc private func doneClicked() {
onDone?()
}
func controlTextDidChange(_ obj: Notification) {
if let textField = obj.object as? NSSearchField {
onSearch?(textField.stringValue)
}
}
func controlTextDidEndEditing(_ obj: Notification) {
let movement = obj.userInfo?["NSTextMovement"] as? Int ?? 0
if movement == NSTextMovement.return.rawValue {
onNext?()
}
}
}
================================================
FILE: FSNotes/View/NameTextField.swift
================================================
//
// NameTextField.swift
// FSNotes
//
// Created by Oleksandr Glushchenko on 10/9/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
class NameTextField: NSTextField {
override func becomeFirstResponder() -> Bool {
let status = super.becomeFirstResponder()
self.textColor = NSColor.init(named: "mainText")
return status
}
}
================================================
FILE: FSNotes/View/NoteCellView.swift
================================================
//
// NoteCellView.swift
// FSNotes
//
// Created by Oleksandr Glushchenko on 7/31/17.
// Copyright © 2017 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
class NoteCellView: NSTableCellView {
@IBOutlet var name: NSTextField!
@IBOutlet var preview: PreviewTextField!
@IBOutlet var date: NSTextField!
@IBOutlet var pin: NSImageView!
@IBOutlet weak var titleConstraint: NSLayoutConstraint!
@IBOutlet weak var imagePreview: NSImageView!
@IBOutlet weak var imagePreviewSecond: NSImageView!
@IBOutlet weak var imagePreviewThird: NSImageView!
public var note: Note?
public var contentLength: Int = 0
public var timestamp: Int64?
private var previewMaximumLineHeight: CGFloat = 12
private let previewLineSpacing: CGFloat = 3
public var imageKeys = [String]()
public var tableView: NotesTableView? {
get {
guard let vc = ViewController.shared() else { return nil }
return vc.notesTableView
}
}
public static var pinImages = [String: NSImage]()
public static var pinEncryptedImages = [String: NSImage]()
public static var pinSharedImages = [String: NSImage]()
override func prepareForReuse() {
super.prepareForReuse()
imagePreview.image = nil
imagePreview.isHidden = true
imagePreviewSecond.image = nil
imagePreviewSecond.isHidden = true
imagePreviewThird.image = nil
imagePreviewThird.isHidden = true
imageKeys = []
timestamp = nil
note = nil
name.stringValue = ""
preview.stringValue = ""
date.stringValue = ""
}
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
renderPin()
name.layer?.zPosition = 1000
if let descriptor = date.font?.fontDescriptor {
date.font = NSFont.init(descriptor: descriptor, size: 11)
}
date.layer?.cornerRadius = 5
date.layer?.zPosition = 1001
date.isHidden = UserDefaultsManagement.hideDate
titleConstraint.constant = UserDefaultsManagement.hideDate ? 0 : 5
if (UserDefaultsManagement.horizontalOrientation) {
preview.isHidden = true
} else {
preview.isHidden = false
}
if UserDefaultsManagement.hidePreviewImages || UserDefaultsManagement.horizontalOrientation {
imagePreview.isHidden = true
imagePreviewSecond.isHidden = true
imagePreviewThird.isHidden = true
}
applyPreviewStyle()
if !UserDefaultsManagement.horizontalOrientation && !UserDefaultsManagement.hidePreviewImages {
self.note?.loadPreviewInfo()
}
}
public func configure(note: Note) {
self.note = note
}
func applyPreviewStyle() {
let additionalHeight = CGFloat(UserDefaultsManagement.cellSpacing)
guard additionalHeight >= 0 else {
applyPreviewAttributes()
return
}
let fontName = UserDefaultsManagement.noteFont.fontName
let previewFontSzie = CGFloat(UserDefaultsManagement.previewFontSize)
guard let font = NSFont(name: fontName, size: previewFontSzie) else { return }
self.previewMaximumLineHeight = font.lineHeightCustom
// vertically align
var numberOfLines = 0
var frameY = 0
if !UserDefaultsManagement.horizontalOrientation && !UserDefaultsManagement.hidePreview {
var size = CGFloat(0)
var i = -1
while true {
if size > additionalHeight - 8 {
break
}
i += 1
if i == 1 {
size += previewMaximumLineHeight
} else {
size += previewLineSpacing + previewMaximumLineHeight
}
}
numberOfLines = i
}
if numberOfLines > 1 {
frameY = Int(
(additionalHeight - previewMaximumLineHeight * CGFloat(numberOfLines) - previewLineSpacing * CGFloat(numberOfLines - 1)) / 2
)
} else {
let lines = numberOfLines > 0 ? numberOfLines : 0
frameY = Int(
(additionalHeight - previewMaximumLineHeight * CGFloat(lines)) / 2
)
}
// save margin
if frameY >= 0 {
let y = CGFloat(Int(frameY))
adjustTopMargin(margin: y)
UserDefaultsManagement.cellViewFrameOriginY = y
}
// apply font and max lines numbers
applyPreviewAttributes(numberOfLines)
}
func applyPreviewAttributes(_ maximumNumberOfLines: Int = 1) {
let string = preview.stringValue
let fontName = UserDefaultsManagement.noteFont.fontName
let previewFontSize = CGFloat(UserDefaultsManagement.previewFontSize)
guard let font = NSFont(name: fontName, size: previewFontSize) else { return }
let textParagraph = NSMutableParagraphStyle()
textParagraph.lineSpacing = previewLineSpacing
textParagraph.maximumLineHeight = previewMaximumLineHeight
let attribs = [
NSAttributedString.Key.font: font,
NSAttributedString.Key.paragraphStyle: textParagraph
]
if maximumNumberOfLines > 0 {
preview.attributedStringValue = NSAttributedString.init(string: string, attributes: attribs)
preview.maximumNumberOfLines = maximumNumberOfLines
} else {
preview.attributedStringValue = NSAttributedString()
preview.maximumNumberOfLines = -1
}
}
public func isSelected() -> Bool {
if let rowView = self.superview as? NSTableRowView, rowView.isSelected, window?.firstResponder == superview?.superview {
return true
}
return false
}
public func isAccentColorTint() -> Bool {
if let rowView = self.superview as? NSTableRowView, !rowView.isSelected {
return true
}
if let rowView = self.superview as? NSTableRowView, rowView.isSelected, window?.firstResponder == superview?.superview {
return false
}
return true
}
func renderPin() {
if let value = objectValue, let note = value as? Note {
if note.isPublished() {
if #available(macOS 12.0, *), let image = NSImage(systemSymbolName: "globe", accessibilityDescription: nil) {
pin.image = image
pin.image?.isTemplate = true
pin.contentTintColor = .controlAccentColor
} else {
pin.image = NSImage(named: "web")
pin.image?.isTemplate = true
pin.contentTintColor = .controlAccentColor
pin.image?.size = NSSize(width: 14, height: 14)
}
pin.isHidden = false
} else if note.isEncrypted() {
let systemName = note.isUnlocked() ? "lock.open" : "lock"
if let image = NSImage(systemSymbolName: systemName, accessibilityDescription: nil) {
pin.image = image
pin.image?.isTemplate = true
pin.contentTintColor = .controlAccentColor
}
pin.isHidden = false
} else {
if #available(macOS 12.0, *), let image = NSImage(systemSymbolName: "pin", accessibilityDescription: nil) {
pin.image = image
pin.image?.isTemplate = true
pin.contentTintColor = .controlAccentColor
} else {
pin.image = NSImage(named: "pin")
pin.image?.isTemplate = true
pin.contentTintColor = .controlAccentColor
pin.image?.size = NSSize(width: 20, height: 20)
}
pin.isHidden = !note.isPinned
}
}
}
public func styleImageView(imageView: ImageView) {
imageView.isHidden = false
imageView.layer?.borderWidth = 1
imageView.layer?.borderColor = Color.darkGray.cgColor
imageView.layer?.cornerRadius = 4
}
public func getPreviewImage(imageUrl: URL, note: Note) -> Image? {
let tempURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("MainNotesList")
if !FileManager.default.fileExists(atPath: tempURL.path) {
try? FileManager.default.createDirectory(at: tempURL, withIntermediateDirectories: false, attributes: nil)
}
if let cacheName = imageUrl.absoluteString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)?.md5 {
let file = tempURL.appendingPathComponent(cacheName)
if FileManager.default.fileExists(atPath: file.path) {
if let data = try? Data(contentsOf: file), let image = NSImage(data: data) {
return image
}
}
do {
let data = try Data(contentsOf: imageUrl)
if let image = NSImage(data: data) {
let size = CGSize(width: 70, height: 70)
if let resized = image.crop(to: size) {
let jpegImageData = resized.jpgData
try? jpegImageData?.write(to: file, options: .atomic)
return resized
}
}
} catch {
print(error.localizedDescription)
}
}
return nil
}
public func adjustPinPosition() {
for constraint in self.constraints {
if constraint.secondAttribute == .leading, let im = constraint.firstItem as? NSImageView {
if im.identifier?.rawValue == "pin" {
if let note = objectValue as? Note, !note.showIconInList() {
constraint.constant = -25
} else {
constraint.constant = 3
}
}
}
}
}
private func adjustTopMargin(margin: CGFloat) {
for constraint in self.constraints {
if constraint.secondAttribute == .top, let item = constraint.firstItem {
if let firstItem = item as? NSImageView, firstItem.identifier?.rawValue == "pin" {
constraint.constant = margin
continue
}
if item.isKind(of: NameTextField.self) {
constraint.constant = margin + 1.5
continue
}
if let item = item as? NSTextField, item.identifier?.rawValue == "cellDate" {
constraint.constant = margin + 3.5
}
}
}
}
public func fixTopConstraint(position: Int?, note: Note) {
guard let tableView = tableView else { return }
for constraint in self.constraints {
if ["firstImageTop", "secondImageTop", "thirdImageTop"].contains(constraint.identifier) {
let ident = constraint.identifier
let height = position != nil ? tableView.tableView(tableView, heightOfRow: position!) : self.frame.height
self.removeConstraint(constraint)
var con = CGFloat(0)
if note.getTitle() != nil {
con += self.name.frame.height
}
let isPreviewExist = note.preview.trim().count > 0
if isPreviewExist {
con += 3 + self.preview.frame.height
}
var diff = (height - con - 48) / 2
diff += con
var imageLink: NSImageView?
switch constraint.identifier {
case "firstImageTop":
imageLink = self.imagePreview
case "secondImageTop":
imageLink = self.imagePreviewSecond
case "thirdImageTop":
imageLink = self.imagePreviewThird
default:
imageLink = self.imagePreview
}
guard let firstItem = imageLink else { continue }
let secondItem = isPreviewExist ? self.preview : self
let secondAttribute: NSLayoutConstraint.Attribute = isPreviewExist ? .bottom : .top
let constant = isPreviewExist ? 6 : diff
let constr = NSLayoutConstraint(item: firstItem, attribute: .top, relatedBy: .equal, toItem: secondItem, attribute: secondAttribute, multiplier: 1, constant: constant)
constr.identifier = ident
self.addConstraint(constr)
}
}
}
public func attachHeaders(note: Note) {
if let title = note.getTitle() {
self.name.stringValue = title
self.preview.stringValue = note.preview
} else {
self.name.stringValue = ""
self.preview.stringValue = ""
}
self.date.stringValue = note.getDateForLabel()
}
}
================================================
FILE: FSNotes/View/NoteRowView.swift
================================================
//
// NoteRowView.swift
// FSNotes
//
// Created by Oleksandr Glushchenko on 7/31/17.
// Copyright © 2017 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
class NoteRowView: NSTableRowView {
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
}
override func drawSeparator(in dirtyRect: NSRect) {
let leftInset: CGFloat = 23
let rightInset: CGFloat = 15
let scale = window?.backingScaleFactor ?? NSScreen.main?.backingScaleFactor ?? 2.0
let pixel = 1.0 / scale
let y = floor(bounds.height - pixel)
let w = max(0, bounds.width - leftInset - rightInset)
NSColor.separatorColor.setFill()
NSBezierPath(rect: NSRect(x: leftInset, y: y, width: w, height: pixel)).fill()
}
}
================================================
FILE: FSNotes/View/NotesCounterView.swift
================================================
//
// NotesCounterView.swift
// FSNotes
//
// Created by Oleksandr Hlushchenko on 14.12.2025.
// Copyright © 2025 Oleksandr Hlushchenko. All rights reserved.
//
import Cocoa
@IBDesignable
class NotesCounterView: NSView {
private var visualEffectView: NSVisualEffectView?
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
setupView()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setupView()
}
private func setupView() {
let effectView = NSVisualEffectView(frame: bounds)
effectView.autoresizingMask = [.width, .height]
effectView.blendingMode = .behindWindow
effectView.material = .contentBackground
effectView.state = .followsWindowActiveState
addSubview(effectView, positioned: .below, relativeTo: nil)
visualEffectView = effectView
}
}
================================================
FILE: FSNotes/View/NotesTableView.swift
================================================
//
// NotesTableView.swift
// FSNotes
//
// Created by Oleksandr Glushchenko on 7/31/17.
// Copyright © 2017 Oleksandr Glushchenko. All rights reserved.
//
import Carbon
import Cocoa
class NotesTableView: NSTableView,
NSTableViewDataSource,
NSTableViewDelegate {
private var noteList = [Note]()
var defaultCell = NoteCellView()
var pinnedCell = NoteCellView()
var storage = Storage.shared()
public var history = [URL]()
public var historyPosition = 0
private var selectedHistory: IndexSet?
override func draw(_ dirtyRect: NSRect) {
allowsTypeSelect = false
self.gridColor = NSColor.clear
self.dataSource = self
self.delegate = self
super.draw(dirtyRect)
}
override func validateUserInterfaceItem(_ item: NSValidatedUserInterfaceItem) -> Bool {
if item.action == #selector(selectAll(_:)) {
return numberOfRows > 0 && allowsMultipleSelection
}
if item.action == #selector(copy(_:)) ||
item.action == #selector(delete(_:)) ||
item.action == #selector(forceDeleteNote(_:)) {
return selectedRowIndexes.count > 0
}
return super.validateUserInterfaceItem(item)
}
override func keyDown(with event: NSEvent) {
guard let vc = self.window?.contentViewController as? ViewController else {
super.keyDown(with: event)
return
}
if event.keyCode == kVK_ANSI_N && event.modifierFlags.contains(.control) {
vc.noteDown(NSMenuItem())
return
}
if event.keyCode == kVK_ANSI_P && event.modifierFlags.contains(.control) {
vc.noteUp(NSMenuItem())
return
}
super.keyDown(with: event)
}
override func keyUp(with event: NSEvent) {
guard let vc = self.window?.contentViewController as? ViewController else {
super.keyUp(with: event)
return
}
if event.keyCode == kVK_Tab && !event.modifierFlags.contains(.control) {
if vc.editor?.isPreviewEnabled() == true {
NSApp.mainWindow?.makeFirstResponder(vc.editor.markdownView)
} else {
vc.focusEditArea()
}
return
}
super.keyUp(with: event)
}
override func mouseDown(with event: NSEvent) {
guard let vc = self.window?.contentViewController as? ViewController else { return }
let point = convert(event.locationInWindow, from: nil)
let row = self.row(at: point)
if row >= 0, noteList.indices.contains(row) {
let note = noteList[row]
if event.modifierFlags.contains(.option) {
NSWorkspace.shared.activateFileViewerSelecting([note.url])
return
}
}
if let selectedProject = vc.sidebarOutlineView.getSelectedProject(),
selectedProject.isLocked()
{
vc.sidebarOutlineView.toggleFolderLock(NSMenuItem())
return
}
UserDataService.instance.searchTrigger = false
super.mouseDown(with: event)
}
func tableView(_ tableView: NSTableView, shouldSelectRow row: Int) -> Bool {
if (noteList.indices.contains(row)) {
saveNavigationHistory(note: noteList[row])
}
return true
}
override func rightMouseDown(with event: NSEvent) {
UserDataService.instance.searchTrigger = false
NSApp.activate(ignoringOtherApps: true)
if let window = self.window {
window.makeKeyAndOrderFront(nil)
}
let point = convert(event.locationInWindow, from: nil)
let rowIndex = row(at: point)
guard rowIndex >= 0, rowIndex < numberOfRows else { return }
saveNavigationHistory(note: noteList[rowIndex])
window?.makeFirstResponder(self)
if !selectedRowIndexes.contains(rowIndex) {
selectRowIndexes(IndexSet(integer: rowIndex), byExtendingSelection: false)
scrollRowToVisible(rowIndex)
}
if rowView(atRow: rowIndex, makeIfNecessary: false) as? NoteRowView != nil,
let menu = menu {
NSMenu.popUpContextMenu(menu, with: event, for: self)
}
}
@IBAction func delete(_ sender: Any) {
guard let vc = ViewController.shared(),
let notes = getSelectedNotes() else { return }
vc.removeNotes(notes: notes, forceRemove: false, rows: selectedRowIndexes)
}
@IBAction func forceDeleteNote(_ sender: Any) {
guard let vc = ViewController.shared(),
let notes = getSelectedNotes() else { return }
vc.removeNotes(notes: notes, forceRemove: true, rows: selectedRowIndexes)
}
public func getNoteList() -> [Note] {
return noteList
}
public func setNoteList(notes: [Note]) {
noteList = notes
}
public func countNotes() -> Int {
return noteList.count
}
public func getIndex(for note: Note) -> Int? {
return noteList.firstIndex(where: {$0 === note})
}
public func getNote(at index: Int) -> Note? {
return noteList.indices.contains(index) ? noteList[index] : nil
}
// Custom note highlight style
func tableView(_ tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView? {
return NoteRowView()
}
// Populate table data
func numberOfRows(in tableView: NSTableView) -> Int {
return noteList.count
}
func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
let height = CGFloat(21 + UserDefaultsManagement.cellSpacing)
guard row < noteList.count else { return height }
let note = noteList[row]
if !note.isLoaded && !note.isLoadedFromCache {
note.load()
}
if !note.isParsed {
note.loadPreviewInfo()
}
if !UserDefaultsManagement.horizontalOrientation
&& !UserDefaultsManagement.hidePreviewImages,
let urls = note.imageUrl,
urls.count > 0{
if note.preview.count == 0 {
if note.getTitle() != nil {
// Title + image
return 79 + 17
}
// Images only
return 79
}
// Title + Prevew + Images
return height + 58
}
// Title + preview
return height
}
// On selected row show notes in right panel
func tableViewSelectionDidChange(_ notification: Notification) {
selectedHistory = selectedRowIndexes
let vc = self.window?.contentViewController as! ViewController
defer {
vc.updateNotesCounter()
}
if vc.editAreaScroll.isFindBarVisible {
let menu = NSMenuItem(title: "", action: nil, keyEquivalent: "")
menu.tag = NSTextFinder.Action.hideFindInterface.rawValue
vc.editor.performTextFinderAction(menu)
}
if UserDataService.instance.isNotesTableEscape {
if vc.sidebarOutlineView.selectedRow == -1 {
UserDataService.instance.isNotesTableEscape = false
}
vc.sidebarOutlineView.deselectAll(nil)
vc.sidebarOutlineView.reloadTags()
vc.editor.clear()
return
}
// Select row
if (noteList.indices.contains(selectedRow)) {
let note = noteList[selectedRow]
guard selectedRowIndexes.count == 0x01 else {
vc.editor.clear()
return
}
vc.editor.changePreviewState(note.previewState)
vc.editor.fill(note: note, highlight: true)
if UserDefaultsManagement.focusInEditorOnNoteSelect && !UserDataService.instance.searchTrigger {
vc.focusEditArea()
}
return
}
// Clean
vc.editor.clear()
if !UserDefaultsManagement.inlineTags {
vc.sidebarOutlineView.deselectAllTags()
}
}
func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {
if (noteList.indices.contains(row)) {
return noteList[row]
}
return nil
}
func tableView(_ tableView: NSTableView, writeRowsWith rowIndexes: IndexSet, to pboard: NSPasteboard) -> Bool {
var urls = [URL]()
var contentUrls = [URL]()
for row in rowIndexes {
let note = noteList[row]
urls.append(note.url)
if let url = note.getContentFileURL() {
contentUrls.append(url)
}
}
pboard.clearContents()
pboard.writeObjects(contentUrls as [NSPasteboardWriting])
if let data = try? NSKeyedArchiver.archivedData(withRootObject: urls, requiringSecureCoding: true) {
pboard.setData(data, forType: NSPasteboard.note)
}
return true
}
@IBAction func copy(_ sender: Any) {
guard let vc = ViewController.shared() else { return }
vc.saveTextAtClipboard()
}
func getNoteFromSelectedRow() -> Note? {
var note: Note? = nil
let selected = self.selectedRow
if (selected < 0) {
return nil
}
if (noteList.indices.contains(selected)) {
note = noteList[selected]
}
return note
}
func getSelectedNote() -> Note? {
var note: Note? = nil
let row = selectedRow
if (noteList.indices.contains(row)) {
note = noteList[row]
}
return note
}
func getSelectedNotes() -> [Note]? {
var notes = [Note]()
for row in selectedRowIndexes {
if (noteList.indices.contains(row)) {
notes.append(noteList[row])
}
}
if notes.isEmpty {
return nil
}
return notes
}
public func deselectNotes() {
self.deselectAll(nil)
}
override func performKeyEquivalent(with event: NSEvent) -> Bool {
if event.modifierFlags.contains(.control) && event.keyCode == kVK_Tab {
return true
}
return super.performKeyEquivalent(with: event)
}
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
guard noteList.indices.contains(row) else {
return nil
}
let note = noteList[row]
if (note.isPinned) {
pinnedCell = makeCell(note: note)
pinnedCell.pin.frame.size.width = 23
return pinnedCell
}
defaultCell = makeCell(note: note)
defaultCell.pin.frame.size.width = 0
return defaultCell
}
func tableView(_ tableView: NSTableView, rowActionsForRow row: Int, edge: NSTableView.RowActionEdge) -> [NSTableViewRowAction] {
guard edge == .trailing else { return [] }
guard noteList.indices.contains(row) else { return [] }
let deleteAction = NSTableViewRowAction(style: .destructive, title: NSLocalizedString("Delete", comment: "")) { [weak self] (action, row) in
guard let self = self else { return }
guard self.noteList.indices.contains(row) else { return }
let noteToDelete = self.noteList[row]
if let vc = self.window?.contentViewController as? ViewController {
vc.removeNotes(notes: [noteToDelete])
}
}
deleteAction.backgroundColor = .systemRed
return [deleteAction]
}
func makeCell(note: Note) -> NoteCellView {
let cell = makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "NoteCellView"), owner: self) as! NoteCellView
cell.imageKeys = []
cell.timestamp = nil
cell.imagePreview.image = nil
cell.imagePreview.isHidden = true
cell.imagePreviewSecond.image = nil
cell.imagePreviewSecond.isHidden = true
cell.imagePreviewThird.image = nil
cell.imagePreviewThird.isHidden = true
cell.configure(note: note)
cell.loadImagesPreview()
cell.attachHeaders(note: note)
return cell
}
override func willOpenMenu(_ menu: NSMenu, with event: NSEvent) {
guard let vc = ViewController.shared() else { return }
if clickedRow > -1 {
selectRowIndexes([clickedRow], byExtendingSelection: false)
}
if selectedRow < 0 { return }
menu.autoenablesItems = false
for menuItem in menu.items {
if vc.processFileMenuItems(menuItem, menuId: "popup") {
menuItem.isEnabled = true
} else {
menuItem.isEnabled = vc.processShareMenuItems(menuItem, menuId: "popup")
}
}
vc.loadMoveMenu()
}
public func selectCurrent() {
guard noteList.count > 0 else { return }
UserDataService.instance.searchTrigger = false
let i = selectedRowIndexes.count > 0 ? selectedRowIndexes : [0]
if let first = i.first {
saveNavigationHistory(note: noteList[first])
selectRowIndexes(i, byExtendingSelection: false)
scrollRowToVisible(first)
}
}
public func selectNext() {
UserDataService.instance.searchTrigger = false
let i = selectedRow + 1
guard noteList.indices.contains(i) else { return }
saveNavigationHistory(note: noteList[i])
selectRowIndexes([i], byExtendingSelection: false)
scrollRowToVisible(i)
}
public func selectPrev() {
UserDataService.instance.searchTrigger = false
let i = selectedRow - 1
guard noteList.indices.contains(i) else { return }
saveNavigationHistory(note: noteList[i])
selectRowIndexes([i], byExtendingSelection: false)
scrollRowToVisible(i)
}
public func selectRow(_ i: Int) {
if (noteList.indices.contains(i)) {
DispatchQueue.main.async {
self.selectRowIndexes([i], byExtendingSelection: false)
self.scrollRowToVisible(i)
}
}
}
public func selectRowAndSidebarItem(note: Note) {
guard let vc = ViewController.shared() else { return }
if let index = getIndex(for: note) {
selectRow(index)
} else {
vc.sidebarOutlineView.select(note: note)
}
}
func setSelected(note: Note) {
if let i = getIndex(for: note) {
selectRow(i)
scrollRowToVisible(i)
}
}
public func select(note: Note) {
if let i = getIndex(for: note) {
if noteList.indices.contains(i) {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.selectRowIndexes([i], byExtendingSelection: false)
self.scrollRowToVisible(i)
}
}
}
}
public func removeRows(notes: [Note]) {
guard let vc = ViewController.shared() else { return }
var indexSet = IndexSet()
for note in notes {
if let i = noteList.firstIndex(where: {$0 === note}) {
indexSet.insert(i)
}
}
guard !indexSet.isEmpty else { return }
beginUpdates()
for i in indexSet.sorted().reversed() {
noteList.remove(at: i)
}
removeRows(at: indexSet, withAnimation: .slideDown)
endUpdates()
if UserDefaultsManagement.inlineTags {
vc.sidebarOutlineView.removeTags(notes: notes)
}
}
public func insertRows(notes: [Note]) {
guard let vc = self.window?.contentViewController as? ViewController else { return }
var insert = [Note]()
for note in notes {
if noteList.first(where: { $0.isEqualURL(url: note.url) }) == nil, vc.storage.searchQuery.isFit(note: note) {
insert.append(note)
}
}
guard !insert.isEmpty else { return }
beginUpdates()
noteList.append(contentsOf: insert)
self.noteList = vc.storage.sortNotes(noteList: self.noteList)
var indexSet = IndexSet()
for note in insert {
if let noteIndex = self.noteList.firstIndex(of: note) {
indexSet.insert(noteIndex)
}
}
self.insertRows(at: indexSet, withAnimation: .effectFade)
endUpdates()
for note in insert {
vc.sidebarOutlineView.insertTags(note: note)
}
}
private func reloadRows(notes: [Note]) {
for note in notes {
note.invalidateCache()
note.loadPreviewInfo()
self.performReload(note: note)
}
}
@objc public func unDelete(_ urls: [URL: URL]) {
guard let vc = ViewController.shared() else { return }
var invertedMapping: [URL: URL] = [:]
for (src, dst) in urls {
do {
if let note = storage.getBy(url: src) {
storage.removeBy(note: note)
if let destination = Storage.shared().getProjectByNote(url: dst) {
note.moveImages(to: destination)
}
}
try FileManager.default.moveItem(at: src, to: dst)
invertedMapping[dst] = src
} catch {
print(error)
}
}
// Register redo (delete again)
if let md = AppDelegate.mainWindowController, !invertedMapping.isEmpty {
let undoManager = md.notesListUndoManager
undoManager.registerUndo(withTarget: self) { notesTableView in
let restoredNotes = invertedMapping.keys.compactMap { url in
vc.storage.getBy(url: url)
}
if !restoredNotes.isEmpty {
vc.removeNotes(notes: restoredNotes, forceRemove: false, rows: nil)
}
}
undoManager.setActionName(NSLocalizedString("Delete", comment: ""))
}
}
public func countVisiblePinned() -> Int {
var i = 0
for note in noteList {
if (note.isPinned) {
i += 1
}
}
return i
}
public func reloadRow(note: Note) {
DispatchQueue.global(qos: .userInitiated).async {
note.invalidateCache()
note.loadPreviewInfo()
DispatchQueue.main.async {
self.performReload(note: note)
}
}
}
private func performReload(note: Note) {
guard let i = self.noteList.firstIndex(of: note) else { return }
let urls = note.imageUrl
if let cell = self.view(atColumn: 0, row: i, makeIfNecessary: false) as? NoteCellView {
cell.date.stringValue = note.getDateForLabel()
cell.loadImagesPreview(position: i, urls: urls)
cell.attachHeaders(note: note)
cell.renderPin()
cell.applyPreviewStyle()
self.noteHeightOfRows(withIndexesChanged: [i])
}
}
public func reloadDate(note: Note) {
DispatchQueue.main.async {
if self.numberOfRows > 0, let i = self.noteList.firstIndex(of: note) {
if let cell = self.view(atColumn: 0, row: i, makeIfNecessary: false) as? NoteCellView {
cell.date.stringValue = note.getDateForLabel()
}
}
}
}
public func saveNavigationHistory(note: Note) {
guard history.last != note.url else {
historyPosition = history.count - 1
return
}
history.append(note.url)
if history.count > 100 {
history.removeFirst()
} else {
historyPosition = history.count - 1
}
}
public func enableLockedProject() {
ViewController.shared()?.lockedFolder.isHidden = false
clean()
}
public func disableLockedProject() {
ViewController.shared()?.lockedFolder.isHidden = true
}
public func clean() {
noteList.removeAll()
reloadData()
}
public func doVisualChanges(results: ([Note], [Note], [Note])) {
guard results.0.count > 0 || results.1.count > 0 || results.2.count > 0 else {
return
}
DispatchQueue.main.async {
if let vc = ViewController.shared(), vc.splitView.subviews[0].frame.width > 10 {
self.removeRows(notes: results.0)
self.insertRows(notes: results.1)
self.reloadRows(notes: results.2)
}
}
}
}
================================================
FILE: FSNotes/View/OutlineHeaderView.swift
================================================
//
// OutlineHeaderView.swift
// FSNotes
//
// Created by Oleksandr Glushchenko on 7/21/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
class OutlineHeaderView: NSView {
override func mouseDown(with event: NSEvent) {
if event.clickCount == 2 {
if let md = AppDelegate.mainWindowController, let actionOnDoubleClick = UserDefaults.standard.object(forKey: "AppleActionOnDoubleClick") as? String {
switch actionOnDoubleClick {
case "Maximize":
md.maximizeWindow()
case "Minimize":
md.window?.performMiniaturize(nil)
default:
break
}
}
} else {
super.mouseDown(with: event)
}
}
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
let lightColor = NSColor(red:1.00, green:1.00, blue:1.00, alpha:1.0)
let darkColor = NSColor(red:0.16, green:0.17, blue:0.18, alpha:1.0)
if NSAppearance.current.isDark {
darkColor.setFill()
} else {
lightColor.setFill()
}
dirtyRect.fill()
}
override var mouseDownCanMoveWindow: Bool {
return true
}
}
================================================
FILE: FSNotes/View/PreviewTextField.swift
================================================
//
// PreviewTextField.swift
// FSNotes
//
// Created by Oleksandr Glushchenko on 10/28/17.
// Copyright © 2017 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
class PreviewTextField: NSTextField {
override var intrinsicContentSize: NSSize {
if maximumNumberOfLines == -1 {
let width = super.intrinsicContentSize.width
return NSSize(width: width, height: 0)
}
return super.intrinsicContentSize
}
override var textColor: NSColor? {
set {
super.textColor = newValue
if attributedStringValue.length > 0 {
var attributes = attributedStringValue.attributes(at: 0, effectiveRange: nil)
attributes[.foregroundColor] = newValue
attributedStringValue = NSAttributedString.init(string: self.stringValue, attributes: attributes)
}
}
get {
return super.textColor
}
}
}
================================================
FILE: FSNotes/View/SearchTextField.swift
================================================
//
// SearchTextField.swift
// FSNotes
//
// Created by Oleksandr Glushchenko on 8/3/17.
// Copyright © 2017 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
import Carbon.HIToolbox
class SearchTextField: NSSearchField, NSSearchFieldDelegate {
public var vcDelegate: ViewController!
private var filterQueue = OperationQueue.init()
public var searchQuery = ""
public var selectedRange = NSRange()
public var skipAutocomplete = false
public var timestamp: Int64?
private var lastQueryLength: Int = 0
private var lastQuery = String()
public var lastSearchQuery = String()
public var searchesMenu: NSMenu? = nil
public func generateRecentMenu() -> NSMenu {
let recentsTitle = NSLocalizedString("Recents", comment: "")
let menu = NSMenu(title: recentsTitle)
menu.autoenablesItems = true
if let recent = UserDefaultsManagement.recentSearches, recent.count > 0 {
let recentsSearchTitle = NSLocalizedString("Recents Search", comment: "")
menu.addItem(withTitle: recentsSearchTitle, action: nil, keyEquivalent: "")
var i = 1
for title in recent {
let menuItem = NSMenuItem(title: title, action: #selector(selectRecent(_:)), keyEquivalent: String(i))
menuItem.target = self
menu.addItem(menuItem)
i += 1
}
menu.addItem(NSMenuItem.separator())
let clearTitle = NSLocalizedString("Clear", comment: "")
let menuItem = NSMenuItem(title: clearTitle, action: #selector(cleanRecents(_:)), keyEquivalent: "d")
menuItem.target = self
menu.addItem(menuItem)
return menu
}
menu.addItem(withTitle: "No Recent Search", action: nil, keyEquivalent: "")
return menu
}
override func textDidEndEditing(_ notification: Notification) {
self.skipAutocomplete = false
self.lastQuery = String()
self.lastQueryLength = 0
addRecent(query: stringValue)
}
override func keyUp(with event: NSEvent) {
if (event.keyCode == kVK_DownArrow) {
vcDelegate.focusTable()
vcDelegate.notesTableView.selectCurrent()
return
}
if (event.keyCode == kVK_LeftArrow && stringValue.count == 0) {
vcDelegate.sidebarOutlineView.window?.makeFirstResponder(vcDelegate.sidebarOutlineView)
let index = vcDelegate.sidebarOutlineView.selectedRowIndexes.count > 0
? vcDelegate.sidebarOutlineView.selectedRowIndexes
: [0]
vcDelegate.sidebarOutlineView.selectRowIndexes(index, byExtendingSelection: false)
return
}
if event.keyCode == kVK_Delete || event.keyCode == kVK_ForwardDelete {
self.skipAutocomplete = true
return
}
}
func control(_ control: NSControl, textView: NSTextView, doCommandBy commandSelector: Selector) -> Bool {
switch commandSelector.description {
case "moveDown:":
if let editor = currentEditor() {
let text = editor.string
let location = editor.selectedRange.location
let length = editor.selectedRange.length
if length > 0 && location > 0 && location <= text.count {
let endIndex = text.index(text.startIndex, offsetBy: location, limitedBy: text.endIndex) ?? text.endIndex
let query = String(text[.. 0 {
self.stringValue = query
}
} else {
if text.count > 0 {
self.stringValue = text
}
}
}
addRecent(query: stringValue)
return true
case "cancelOperation:":
self.skipAutocomplete = true
self.lastQuery = String()
self.filterQueue.cancelAllOperations()
return true
case "deleteBackward:":
self.skipAutocomplete = true
self.lastQuery = String()
self.filterQueue.cancelAllOperations()
textView.deleteBackward(self)
return true
case "insertNewline:", "insertNewlineIgnoringFieldEditor:":
if let note = vcDelegate.editor.getSelectedNote(), stringValue.utf16.count > 0, note.title.lowercased() == stringValue.lowercased() || note.fileName.lowercased() == stringValue.lowercased() {
if note.title.lowercased() == stringValue.lowercased() && note.title != stringValue {
stringValue = note.title
}
if note.fileName.lowercased() == stringValue.lowercased() && note.fileName != stringValue {
stringValue = note.fileName
}
markCompleteonAsSuccess()
if vcDelegate.vcEditor?.isPreviewEnabled() == true
&& vcDelegate.editor.note?.container != .encryptedTextPack {
vcDelegate.vcEditor?.disablePreviewEditorAndNote()
DispatchQueue.main.async {
self.vcDelegate.refillEditArea()
NSApp.mainWindow?.makeFirstResponder(self.vcDelegate.editor)
}
} else {
DispatchQueue.main.async {
self.vcDelegate.focusEditArea()
}
}
} else {
vcDelegate.makeNote(self)
}
addRecent(query: stringValue)
return true
case "insertTab:":
markCompleteonAsSuccess()
if vcDelegate.vcEditor?.isPreviewEnabled() == true {
NSApp.mainWindow?.makeFirstResponder(vcDelegate.editor.markdownView)
} else {
vcDelegate.focusEditArea()
}
vcDelegate.editor.scrollToCursor()
return true
case "deleteWordBackward:":
self.skipAutocomplete = true
self.lastQuery = String()
self.filterQueue.cancelAllOperations()
textView.deleteWordBackward(self)
lastQueryLength = self.stringValue.utf16.count
return true
case "noop:":
if let event = NSApp.currentEvent, event.modifierFlags.contains(.command) && event.keyCode == kVK_Return {
vcDelegate.makeNote(self)
return true
}
return false
default:
return false
}
}
func controlTextDidChange(_ obj: Notification) {
search()
// Clean as lastSearchQuery used by highlighter
if stringValue.count == 0 {
lastSearchQuery = String()
}
}
public func suggestAutocomplete(_ note: Note, filter: String) {
guard note.title.lowercased() != filter.lowercased(),
let editor = currentEditor()
else { return }
if note.title.lowercased().starts(with: filter.lowercased()) {
if note.title.lowercased() != stringValue.lowercased() {
stringValue = filter + String(note.title.utf16.suffix(note.title.utf16.count - filter.utf16.count))!
lastQuery = stringValue
lastQueryLength = stringValue.utf16.count
}
editor.selectedRange = NSRange(filter.utf16.count.. self.lastQueryLength {
self.skipAutocomplete = false
}
self.lastQueryLength = searchText.count
if let query = getSearchTextExceptCompletion() {
self.lastSearchQuery = query
}
self.filterQueue.cancelAllOperations()
self.filterQueue.addOperation {
self.vcDelegate.updateTable() {
if let note = self.vcDelegate.notesTableView.getNoteList().first {
DispatchQueue.main.async() {
if let searchQuery = self.getSearchTextExceptCompletion() {
if self.lastSearchQuery != searchQuery {
return
}
self.savePasteboard(value: searchQuery)
let search = searchQuery.lowercased()
if note.title.lowercased() == search || UserDefaultsManagement.textMatchAutoSelection {
self.vcDelegate.notesTableView.setSelected(note: note)
self.stringValue = searchQuery
return
} else if !self.skipAutocomplete && (note.title.lowercased().starts(with: search)
|| note.fileName.lowercased().starts(with: search))
{
self.vcDelegate.notesTableView.setSelected(note: note)
self.suggestAutocomplete(note, filter: searchQuery)
return
} else {
self.vcDelegate.editor.clear()
}
}
}
} else {
DispatchQueue.main.async {
self.vcDelegate.editor.clear()
}
}
}
}
}
// Used in NSTextFinder cmd-f | cmd-g
private func savePasteboard(value: String) {
let pb = NSPasteboard(name: NSPasteboard.Name.find)
pb.declareTypes([.textFinderOptions, .string], owner: nil)
pb.setString(value, forType: NSPasteboard.PasteboardType.string)
}
private func getSearchTextExceptCompletion() -> String? {
guard let editor = currentEditor() else { return nil }
if editor.selectedRange.location > 0 {
return String(editor.string.prefix(editor.selectedRange.location))
}
return nil
}
private func markCompleteonAsSuccess() {
currentEditor()?.selectedRange = NSRange(location: stringValue.count, length: 0)
self.skipAutocomplete = false
self.lastQuery = String()
self.lastQueryLength = 0
}
@IBAction public func selectRecent(_ sender: NSMenuItem) {
stringValue = sender.title
search()
}
@IBAction public func cleanRecents(_ sender: NSMenuItem) {
UserDefaultsManagement.recentSearches = nil
searchesMenu = generateRecentMenu()
}
public func addRecent(query: String) {
let query = query.trim()
guard query.trim().count > 0 else { return }
var recents = UserDefaultsManagement.recentSearches ?? [String]()
if recents.contains(query) {
if let index = recents.firstIndex(of: query) {
recents.remove(at: index)
}
}
recents.insert(query, at: 0)
if recents.count > 9 {
recents = recents.dropLast()
}
UserDefaultsManagement.recentSearches = recents
searchesMenu = generateRecentMenu()
}
}
================================================
FILE: FSNotes/View/SidebarCellView.swift
================================================
//
// SidebarCellView.swift
// FSNotes
//
// Created by Oleksandr Glushchenko on 4/7/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
class SidebarCellView: NSTableCellView {
@IBOutlet weak var icon: NSImageView!
@IBOutlet weak var label: NSTextField!
public var type: SidebarItemType?
public var storage = Storage.shared()
@IBAction func projectName(_ sender: NSTextField) {
let cell = sender.superview as? SidebarCellView
guard let project = cell?.objectValue as? Project else { return }
let src = project.url
let dst = project.url.deletingLastPathComponent().appendingPathComponent(sender.stringValue, isDirectory: true)
do {
if FileManager.default.fileExists(atPath: dst.path) {
sender.stringValue = project.url.lastPathComponent
return
}
try FileManager.default.moveItem(at: src, to: dst)
} catch {
sender.stringValue = project.url.lastPathComponent
let alert = NSAlert()
alert.messageText = error.localizedDescription
alert.runModal()
}
}
}
================================================
FILE: FSNotes/View/SidebarHeaderCellView.swift
================================================
//
// SidebarHeaderCellView.swift
// FSNotes
//
// Created by Олександр Глущенко on 15.10.2019.
// Copyright © 2019 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
class SidebarHeaderCellView: NSTableCellView {
@IBOutlet weak var label: NSTextField!
@IBOutlet weak var icon: NSImageView!
}
================================================
FILE: FSNotes/View/SidebarNotesView.swift
================================================
//
// SidebarNotesView.swift
// FSNotes
//
// Created by Oleksandr Glushchenko on 4/9/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
class SidebarNotesView: NSView {
// override func draw(_ dirtyRect: NSRect) {
// super.draw(dirtyRect)
//
// if UserDefaultsManagement.appearanceType != AppearanceType.Custom, #available(OSX 10.13, *) {
// NSColor(named: "mainBackground")!.setFill()
// __NSRectFill(dirtyRect)
// } else {
// layer?.backgroundColor = NSColor.white.cgColor
// }
// }
}
================================================
FILE: FSNotes/View/SidebarOutlineView.swift
================================================
//
// SidebarProjectView.swift
// FSNotes
//
// Created by Oleksandr Glushchenko on 4/9/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
import Foundation
import Carbon.HIToolbox
class SidebarOutlineView: NSOutlineView,
NSOutlineViewDelegate,
NSOutlineViewDataSource {
public var sidebarItems: [Any]? = nil
public var viewDelegate: ViewController? = nil
public var storage = Storage.shared()
public var isFirstLaunch = true
public var selectNote: Note? = nil
private var selectedSidebarItems: [SidebarItem]?
private var selectedProjects: [Project]?
private var selectedTags: [String]?
private var cellView: SidebarCellView?
// MARK: Override
override func rightMouseDown(with event: NSEvent) {
guard let vc = ViewController.shared() else { return }
let point = convert(event.locationInWindow, from: nil)
let rowIndex = row(at: point)
if (rowIndex < 0 || self.numberOfRows < rowIndex) {
return
}
if let item = item(atRow: rowIndex) as? SidebarItem {
if item.type == .Separator {
return
}
}
if !selectedRowIndexes.contains(rowIndex) {
selectRowIndexes(IndexSet(integer: rowIndex), byExtendingSelection: false)
scrollRowToVisible(rowIndex)
}
if rowView(atRow: rowIndex, makeIfNecessary: false) as? SidebarTableRowView != nil {
window?.makeFirstResponder(self)
if let menu = menu {
menu.autoenablesItems = false
for item in menu.items {
item.isEnabled = vc.processLibraryMenuItems(item, menuId: "folderPopup")
}
NSMenu.popUpContextMenu(menu, with: event, for: self)
}
}
}
override func draw(_ dirtyRect: NSRect) {
allowsTypeSelect = false
delegate = self
dataSource = self
registerForDraggedTypes([
NSPasteboard.PasteboardType(kUTTypeFileURL as String),
NSPasteboard.note,
NSPasteboard.project
])
super.draw(dirtyRect)
}
override func keyDown(with event: NSEvent) {
// Tab to search
if event.keyCode == kVK_Tab {
self.viewDelegate?.search.becomeFirstResponder()
return
}
// Focus on note list
if event.keyCode == kVK_RightArrow {
if let fr = NSApp.mainWindow?.firstResponder, let vc = self.viewDelegate, fr.isKind(of: SidebarOutlineView.self) {
if let tag = item(atRow: selectedRow) as? FSTag, tag.isExpandable(), !isItemExpanded(tag) {
super.keyDown(with: event)
return
}
if let project = item(atRow: selectedRow) as? Project, project.isExpandable(), !isItemExpanded(project) {
super.keyDown(with: event)
return
}
if let project = item(atRow: selectedRow) as? Project, project.isLocked() {
toggleFolderLock(NSMenuItem())
return
}
vc.notesTableView.selectCurrent()
NSApp.mainWindow?.makeFirstResponder(vc.notesTableView)
return
}
}
super.keyDown(with: event)
}
override func expandItem(_ item: Any?, expandChildren: Bool) {
if let project = item as? Project {
project.isExpanded = true
}
super.expandItem(item, expandChildren: expandChildren)
storage.saveProjectsExpandState()
}
override func collapseItem(_ item: Any?, collapseChildren: Bool) {
if let project = item as? Project {
project.isExpanded = false
}
super.collapseItem(item, collapseChildren: collapseChildren)
storage.saveProjectsExpandState()
}
override func selectRowIndexes(_ indexes: IndexSet, byExtendingSelection extend: Bool) {
guard let index = indexes.first else { return }
var extend = extend
if (item(atRow: index) as? FSTag) != nil {
for i in selectedRowIndexes {
if nil != item(atRow: i) as? FSTag {
deselectRow(i)
}
}
extend = true
}
super.selectRowIndexes(indexes, byExtendingSelection: extend)
}
// MARK: Delegates
func outlineView(_ outlineView: NSOutlineView, acceptDrop info: NSDraggingInfo, item: Any?, childIndex index: Int) -> Bool {
guard let vc = ViewController.shared() else { return false }
guard let sidebarItems = self.sidebarItems else { return false }
// Drag and drop project (reorder)
if let data = info.draggingPasteboard.string(forType: NSPasteboard.project) {
let url = URL(fileURLWithPath: data)
guard let project = Storage.shared().getProjectBy(url: url) else { return false }
// Get src index for child and root folders
var srcIndex: Int?
let dstProject = item as? Project
if dstProject != nil, let srcParent = project.parent, !srcParent.isDefault {
srcIndex = srcParent.child.firstIndex(where: { $0 === project })
} else {
srcIndex = sidebarItems.firstIndex(where: { $0 as? Project === project })
}
guard let srcIndex = srcIndex else { return false }
var diff = 0
if srcIndex > index {
diff = 0
} else {
diff = -1
}
outlineView.moveItem(at: srcIndex, inParent: item, to: index + diff, inParent: item)
if item == nil {
self.sidebarItems?.remove(at: srcIndex)
self.sidebarItems?.insert(project, at: index + diff)
// Save order
if let si = self.sidebarItems {
var toSave = [Project]()
for sidebarItem in si {
// Save all projects from this level
if let siProject = sidebarItem as? Project, project.parent === siProject.parent
|| (project.isBookmark && siProject.parent?.isDefault == true)
|| (project.parent?.isDefault == true && siProject.isBookmark)
{
toSave.append(siProject)
}
}
saveOrderFor(projects: toSave)
}
} else {
project.parent?.child.remove(at: srcIndex)
project.parent?.child.insert(project, at: index + diff)
// Save order
if let projects = project.parent?.child {
saveOrderFor(projects: projects)
}
}
return true
}
// Drag and drop Note
let board = info.draggingPasteboard
var urls = [URL]()
if let data = info.draggingPasteboard.data(forType: NSPasteboard.note),
let unarchivedData = try? NSKeyedUnarchiver.unarchivedObject(ofClasses: [NSArray.self, NSURL.self], from: data) as? [URL] {
urls = unarchivedData
}
// tags
if let tag = item as? FSTag {
if urls.count > 0, Storage.shared().getBy(url: urls.first!) != nil {
for url in urls {
if let note = Storage.shared().getBy(url: url) {
note.addTag(tag.getFullName())
_ = note.scanContentTags()
viewDelegate?.notesTableView.reloadRow(note: note)
if viewDelegate?.editor.note == note {
viewDelegate?.refillEditArea(force: true)
}
}
}
}
return true
}
// projects
var maybeProject: Project?
if let sidebarItem = item as? SidebarItem, let sidebarProject = sidebarItem.project {
maybeProject = sidebarProject
}
if let sidebarProject = item as? Project {
maybeProject = sidebarProject
}
if let sidebarItem = item as? SidebarItem, sidebarItem.type == .Inbox {
maybeProject = Storage.shared().getDefault()
}
guard let project = maybeProject else { return false }
if urls.count > 0, Storage.shared().getBy(url: urls.first!) != nil {
var notes = [Note]()
for url in urls {
if let note = Storage.shared().getBy(url: url) {
notes.append(note)
}
}
if project.isTrash {
vc.editor.clear()
vc.storage.removeNotes(notes: notes) { _ in
DispatchQueue.main.async {
vc.notesTableView.removeRows(notes: notes)
}
}
} else {
vc.moveReq(notes: notes, project: project) { success in
guard success else { return }
}
}
return true
}
guard let draggedURLs = board.readObjects(forClasses: [NSURL.self], options: nil) as? [URL] else { return false }
for url in draggedURLs {
var isDirectory = ObjCBool(true)
if FileManager.default.fileExists(atPath: url.path, isDirectory: &isDirectory), isDirectory.boolValue && !url.path.contains(".textbundle") {
let dirName = url.lastPathComponent
let dirDst = project.url.appendingPathComponent(dirName)
if !FileManager.default.fileExists(atPath: dirDst.path) {
try? FileManager.default.copyItem(at: url, to: dirDst)
} else {
let alert = NSAlert()
alert.alertStyle = .critical
let information = NSLocalizedString("Folder with name '%@' already exist", comment: "")
alert.informativeText = String(format: information, dirName)
alert.runModal()
}
} else {
_ = vc.copy(project: project, url: url)
}
}
return true
}
func outlineView(_ outlineView: NSOutlineView, pasteboardWriterForItem item: Any) -> NSPasteboardWriting? {
guard let project = item as? Project, getSidebarTags() == nil else { return nil }
let item = NSPasteboardItem()
item.setString(project.url.path, forType: NSPasteboard.project)
return item
}
func outlineView(_ outlineView: NSOutlineView, validateDrop info: NSDraggingInfo, proposedItem item: Any?, proposedChildIndex index: Int) -> NSDragOperation {
if let archivedData = info.draggingPasteboard.string(forType: NSPasteboard.project) {
let url = URL(fileURLWithPath: archivedData)
guard let project = Storage.shared().getProjectBy(url: url) else {
return NSDragOperation()
}
let dstProject = item as? Project
if isAllowedDropIndex(srcProject: project, dstProject: dstProject, dstIndex: index) {
return .move
}
return NSDragOperation()
}
let board = info.draggingPasteboard
var isLocalNote = false
var urls = [URL]()
if let archivedData = info.draggingPasteboard.data(forType: NSPasteboard.note),
let urlsUnarchived = try? NSKeyedUnarchiver.unarchivedObject(ofClasses: [NSArray.self, NSURL.self], from: archivedData) as? [URL] {
urls = urlsUnarchived
if let url = urls.first, Storage.shared().getBy(url: url) != nil {
isLocalNote = true
}
// Disable drag and drop notes between sidebar items
if index > -1 {
return NSDragOperation(rawValue: 0)
}
}
if item as? Project != nil || (item as? SidebarItem)?.project != nil {
return isLocalNote ? .move : .copy
}
if item as? FSTag != nil {
return .copy
}
guard let sidebarItem = item as? SidebarItem else { return NSDragOperation() }
switch sidebarItem.type {
case .Inbox:
return .move
case .Trash:
if isLocalNote {
return .move
}
break
case .Separator:
guard sidebarItem.isSelectable() else { break }
if isLocalNote {
return .move
}
if let urls = board.readObjects(forClasses: [NSURL.self], options: nil) as? [URL], urls.count > 0 {
return .copy
}
break
default:
break
}
return NSDragOperation()
}
func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int {
if let tag = item as? FSTag {
return tag.child.count
}
if let project = item as? Project {
return project.child.count
}
if let sidebar = sidebarItems, item == nil {
return sidebar.count
}
return 0
}
func outlineView(_ outlineView: NSOutlineView, heightOfRowByItem item: Any) -> CGFloat {
if let si = item as? SidebarItem {
if si.type == .Separator {
return 15
}
if si.type == .Header {
return 50
}
}
return 25
}
func outlineView(_ outlineView: NSOutlineView, isItemExpandable item: Any) -> Bool {
if let tag = item as? FSTag {
return tag.isExpandable()
}
if let project = item as? Project {
return project.isExpandable()
}
return false
}
func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any {
if let tag = item as? FSTag {
return tag.child[index]
}
if let project = item as? Project {
return project.child[index]
}
if let sidebar = sidebarItems, item == nil {
return sidebar[index]
}
return String()
}
func outlineView(_ outlineView: NSOutlineView, objectValueFor tableColumn: NSTableColumn?, byItem item: Any?) -> Any? {
return item
}
func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? {
let cell = outlineView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "DataCell"), owner: self) as! SidebarCellView
cell.icon.contentTintColor = NSColor.controlAccentColor
if let tag = item as? FSTag {
cell.type = .Tag
let image = NSImage(named: "sidebar_tag")
image?.isTemplate = true
cell.icon.image = image
cell.icon.isHidden = false
cell.label.frame.origin.x = 25
cell.textField?.stringValue = tag.getName()
} else if let project = item as? Project {
if project.isEncrypted {
if project.isLocked() {
cell.type = .ProjectEncryptedLocked
let image = NSImage(named: "sidebar_project_encrypted_locked")
image?.isTemplate = true
cell.icon.image = image
} else {
cell.type = .ProjectEncryptedUnlocked
let image = NSImage(named: "sidebar_project_encrypted_unlocked")
image?.isTemplate = true
cell.icon.image = image
}
} else {
cell.type = .Project
let image = NSImage(named: "sidebar_project")
image?.isTemplate = true
cell.icon.image = image
}
cell.icon.isHidden = false
cell.label.frame.origin.x = 25
cell.textField?.stringValue = project.label
} else if let si = item as? SidebarItem {
let name = si.type == .Separator ? "" : si.name
cell.textField?.stringValue = name
cell.type = si.type
if let name = si.type.icon, let image = si.getIcon(name: name) {
cell.icon.image = image
} else {
cell.icon.image = nil
}
cell.icon.isHidden = false
cell.label.frame.origin.x = 25
if si.type == .Header {
let cell = outlineView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "HeaderCell"), owner: self) as! SidebarHeaderCellView
cell.label.frame.origin.x = 2
cell.label.stringValue = name
return cell
}
}
return cell
}
func outlineView(_ outlineView: NSOutlineView, isGroupItem item: Any) -> Bool {
return false
}
func outlineView(_ outlineView: NSOutlineView, shouldSelectItem item: Any) -> Bool {
if nil != item as? FSTag {
return true
}
if nil != item as? Project {
return true
}
if let sidebarItem = item as? SidebarItem {
return sidebarItem.isSelectable()
}
return false
}
func outlineView(_ outlineView: NSOutlineView, rowViewForItem item: Any) -> NSTableRowView? {
return SidebarTableRowView(frame: NSZeroRect)
}
func outlineViewSelectionDidChange(_ notification: Notification) {
defer {
isFirstLaunch = false
}
if Storage.shared().welcomeProject != nil {
Storage.shared().welcomeProject = nil
return
}
guard let vd = viewDelegate else { return }
guard let view = notification.object as? NSOutlineView else { return }
viewDelegate?.notesTableView.disableLockedProject()
if UserDataService.instance.isNotesTableEscape {
UserDataService.instance.isNotesTableEscape = false
}
let hasChangedSidebarItemsState = isChangedSidebarItemsState()
let hasChangedProjectsState = isChangedProjectsState()
let hasChangedTagsState = isChangedTagsState()
if hasChangedTagsState || hasChangedProjectsState || hasChangedSidebarItemsState {
vd.editor.clear()
}
let i = view.selectedRow
if UserDefaultsManagement.inlineTags,
view.item(atRow: i) as? FSTag == nil,
hasChangedProjectsState || hasChangedSidebarItemsState {
reloadTags()
}
if let item = view.item(atRow: i) as? SidebarItem {
if UserDefaultsManagement.lastSidebarItem == item.type.rawValue
&& !hasChangedTagsState
&& !isFirstLaunch {
return
}
UserDefaultsManagement.lastSidebarItem = item.type.rawValue
UserDefaultsManagement.lastProjectURL = nil
}
if let selectedProject = view.item(atRow: i) as? Project {
if UserDefaultsManagement.lastProjectURL == selectedProject.url
&& !hasChangedTagsState
&& !isFirstLaunch {
return
}
UserDefaultsManagement.lastProjectURL = selectedProject.url
UserDefaultsManagement.lastSidebarItem = nil
if selectedProject.isLocked() {
viewDelegate?.notesTableView.enableLockedProject()
}
}
if !isFirstLaunch {
vd.search.stringValue = ""
}
guard !UserDataService.instance.skipSidebarSelection else {
UserDataService.instance.skipSidebarSelection = false
return
}
vd.buildSearchQuery()
vd.updateTable() {
if let note = self.selectNote {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
if let i = vd.notesTableView.getIndex(for: note) {
vd.notesTableView.selectRowIndexes([i], byExtendingSelection: false)
vd.notesTableView.scrollRowToVisible(i)
}
}
self.selectNote = nil
}
}
}
// MARK: Actions
@IBAction func revealInFinder(_ sender: Any) {
if getSidebarItems()?.first?.type == .Inbox {
if let url = Storage.shared().getDefault()?.url {
NSWorkspace.shared.activateFileViewerSelecting([url])
}
return
}
guard let projects = getSelectedProjects() else { return }
let urls = projects.map { $0.url }
if urls.count > 0 {
NSWorkspace.shared.activateFileViewerSelecting(urls)
}
}
@IBAction func renameFolderMenu(_ sender: Any) {
guard let vc = ViewController.shared(),
let sidebarOutlineView = vc.sidebarOutlineView else { return }
if sidebarOutlineView.getSidebarTags() != nil {
sidebarOutlineView.renameTag(NSMenuItem())
return
}
guard sidebarOutlineView.getSelectedProject() != nil else { return }
guard let projectRow = sidebarOutlineView.rowView(atRow: sidebarOutlineView.selectedRow, makeIfNecessary: false),
let cell = projectRow.view(atColumn: 0) as? SidebarCellView else { return }
cell.label.isEditable = true
cell.label.becomeFirstResponder()
}
@IBAction public func removeTags(_ sender: NSMenuItem) {
guard let vc = ViewController.shared() else { return }
guard let window = MainWindowController.shared() else { return }
guard let selectedTags = vc.sidebarOutlineView.getSidebarTags() else { return }
let alert = NSAlert()
vc.alert = alert
let messageText = NSLocalizedString("Are you really want to remove %d tag(s)? This action can not be undone.", comment: "")
alert.messageText = NSLocalizedString("Remove Tags", comment: "")
alert.informativeText = String(format: messageText, selectedTags.count)
alert.alertStyle = .informational
alert.addButton(withTitle: NSLocalizedString("Remove", comment: ""))
alert.addButton(withTitle: NSLocalizedString("Cancel", comment: ""))
alert.beginSheetModal(for: window) { (returnCode: NSApplication.ModalResponse) -> Void in
if returnCode == NSApplication.ModalResponse.alertFirstButtonReturn {
let notes = vc.notesTableView.getNoteList()
var plainTags = [String]()
for index in vc.sidebarOutlineView.selectedRowIndexes {
if let tag = vc.sidebarOutlineView.item(atRow: index) as? FSTag {
plainTags.append(contentsOf: tag.getAllChild())
}
}
vc.sidebarOutlineView.remove(tags: plainTags, from: notes)
}
NSApp.mainWindow?.makeFirstResponder(vc.sidebarOutlineView)
vc.alert = nil
}
}
@IBAction func renameTag(_ sender: NSMenuItem) {
guard let vc = ViewController.shared() else { return }
guard let window = MainWindowController.shared() else { return }
guard let tags = vc.sidebarOutlineView.getRawSidebarTags() else { return }
let alert = NSAlert()
vc.alert = alert
let field = NSTextField(frame: NSRect(x: 0, y: 0, width: 290, height: 20))
if let name = tags.first?.getFullName() {
field.stringValue = name
}
alert.messageText = NSLocalizedString("Rename Tags", comment: "")
alert.informativeText = NSLocalizedString("Please enter tag name:", comment: "")
alert.accessoryView = field
alert.alertStyle = .informational
alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
alert.addButton(withTitle: NSLocalizedString("Cancel", comment: ""))
alert.beginSheetModal(for: window) { (returnCode: NSApplication.ModalResponse) -> Void in
if returnCode == NSApplication.ModalResponse.alertFirstButtonReturn {
let name = field.stringValue.replacingOccurrences(of: "\\s", with: "", options: NSString.CompareOptions.regularExpression, range: nil)
self.rename(tags: tags, name: name)
}
NSApp.mainWindow?.makeFirstResponder(vc.sidebarOutlineView)
vc.alert = nil
}
field.becomeFirstResponder()
}
@IBAction func delete(_ sender: Any) {
guard let vc = ViewController.shared(),
let sidebarOutlineView = vc.sidebarOutlineView else { return }
if sidebarOutlineView.getSidebarTags() != nil {
sidebarOutlineView.removeTags(NSMenuItem())
return
}
guard let projects = sidebarOutlineView.getSelectedProjects() else { return }
for project in projects {
delete(project: project)
}
UserDefaultsManagement.lastSidebarItem = nil
UserDefaultsManagement.lastProjectURL = nil
UserDefaultsManagement.lastSelectedURL = nil
}
private func delete(project: Project) {
guard let vc = ViewController.shared() else { return }
if !(project.isDefault || project.isBookmark) {
guard let window = MainWindowController.shared() else { return }
let alert = NSAlert.init()
vc.alert = alert
let messageText = NSLocalizedString("Are you sure you want to remove project \"%@\" and all files inside?", comment: "")
alert.messageText = String(format: messageText, project.label)
alert.informativeText = NSLocalizedString("This action cannot be undone.", comment: "Delete menu")
alert.addButton(withTitle: NSLocalizedString("Remove", comment: "Delete menu"))
alert.addButton(withTitle: NSLocalizedString("Cancel", comment: "Delete menu"))
alert.beginSheetModal(for: window) { (returnCode: NSApplication.ModalResponse) -> Void in
if returnCode == NSApplication.ModalResponse.alertFirstButtonReturn {
do {
if let note = vc.editor.note {
vc.closeAllOpenedWindows(where: note)
if note.project == project {
vc.editor.clear()
}
}
self.removeRows(projects: [project])
try FileManager.default.removeItem(at: project.url)
self.storage.cleanCachedTree(url: project.url)
} catch {
print(error)
}
NSApp.mainWindow?.makeFirstResponder(vc.sidebarOutlineView)
}
vc.alert = nil
}
return
}
let projects = storage.getAvailableProjects().filter({ $0.url.path.starts(with: project.url.path) })
for item in projects {
SandboxBookmark().removeBy(item.url)
}
vc.sidebarOutlineView.removeRows(projects: projects)
vc.sidebarOutlineView.selectRowIndexes([0], byExtendingSelection: false)
vc.updateTable()
}
@IBAction func removeFolderEncryption(_ sender: NSMenuItem) {
guard let vc = ViewController.shared(),
let projects = vc.sidebarOutlineView.getSelectedProjects() else { return }
guard let firstProject = projects.first else { return }
if firstProject.isEncrypted {
vc.getMasterPassword() { password in
vc.sidebarOutlineView.decrypt(projects: projects, password: password)
}
}
}
@IBAction func toggleFolderLock(_ sender: NSMenuItem) {
guard let vc = ViewController.shared(),
let projects = vc.sidebarOutlineView.getSelectedProjects() else { return }
guard let firstProject = projects.first else { return }
// Encrypt
if !firstProject.isEncrypted {
vc.getMasterPassword(forEncrypt: true) { password in
vc.sidebarOutlineView.encrypt(projects: projects, password: password)
}
return
}
// Lock password exist
if firstProject.password != nil {
vc.sidebarOutlineView.lock(projects: projects)
// Unlock
} else {
let action = sender.identifier?.rawValue
vc.getMasterPassword() { password in
vc.sidebarOutlineView.unlock(projects: projects, password: password, action: action)
}
}
}
public func decrypt(projects: [Project], password: String) {
var decryptedQty = 0
var total = 0
for project in projects {
let notes = project.storage.getNotesBy(project: project)
total += notes.count
let decrypted = project.decrypt(password: password)
decryptedQty = decrypted.count
self.showTags(notes: decrypted)
}
DispatchQueue.main.async {
guard decryptedQty > 0 || total == 0 else {
self.wrongPassAlert()
return
}
guard let vc = ViewController.shared() else { return }
vc.notesTableView.disableLockedProject()
vc.notesTableView.reloadData()
vc.updateTable()
self.reloadData(forRowIndexes: self.selectedRowIndexes, columnIndexes: [0])
}
}
public func encrypt(projects: [Project], password: String) {
for project in projects {
let encrypted = project.encrypt(password: password)
self.hideTags(notes: encrypted)
}
DispatchQueue.main.async {
guard let vc = ViewController.shared() else { return }
vc.notesTableView.enableLockedProject()
self.reloadData(forRowIndexes: self.selectedRowIndexes, columnIndexes: [0])
// Lock all editors
let editors = AppDelegate.getEditTextViews()
for editor in editors {
if let evc = editor.editorViewController {
evc.refillEditArea()
}
}
}
}
public func lock(projects: [Project]) {
guard let vc = ViewController.shared() else { return }
var locked = [Note]()
for project in projects {
locked.append(contentsOf: project.lock())
}
hideTags(notes: locked)
if let selectedProject = getSelectedProject(), projects.contains(selectedProject) {
vc.notesTableView.enableLockedProject()
vc.updateTable()
vc.editor.clear()
}
for project in projects {
reloadItem(project)
}
// Lock all editors
let editors = AppDelegate.getEditTextViews()
for editor in editors {
if let evc = editor.editorViewController {
evc.refillEditArea()
}
}
}
public func unlock(projects: [Project], password: String, action: String? = nil) {
var unlocked = [Note]()
var isEmptyDir = false
for project in projects {
let result = project.unlock(password: password)
// no notes
if result.0.count == 0 {
isEmptyDir = true
continue
}
unlocked.append(contentsOf: result.1)
}
self.showTags(notes: unlocked)
DispatchQueue.main.async {
if unlocked.count > 0 || (projects.count == 1 && isEmptyDir) {
guard let vc = ViewController.shared() else { return }
vc.notesTableView.disableLockedProject()
vc.updateTable() {
if action == "menu.newNote" {
DispatchQueue.main.async {
_ = vc.createNote()
}
}
}
self.reloadData(forRowIndexes: self.selectedRowIndexes, columnIndexes: [0])
} else {
self.wrongPassAlert()
}
}
}
private func wrongPassAlert() {
let alert = NSAlert()
alert.alertStyle = .critical
alert.messageText = NSLocalizedString("Wrong password", comment: "")
alert.beginSheetModal(for: self.window!) { (returnCode: NSApplication.ModalResponse) -> Void in }
}
private func hideTags(notes: [Note]) {
var notesTags = [String]()
for note in notes {
let tags = note.tags
note.tags.removeAll()
for tag in tags {
if !notesTags.contains(tag) {
notesTags.append(tag)
}
}
}
DispatchQueue.main.async {
self.removeTags(notesTags)
}
}
private func showTags(notes: [Note]) {
var notesTags = [String]()
for note in notes {
if note.tags.count == 0 {
_ = note.scanContentTags().0
}
for insertTag in note.tags {
if !notesTags.contains(insertTag) {
notesTags.append(insertTag)
}
}
}
DispatchQueue.main.async {
self.addTags(notesTags)
}
}
// MARK: Functions
private func isAllowedDropIndex(srcProject: Project, dstProject: Project?, dstIndex: Int) -> Bool {
guard let sidebarItems = self.sidebarItems else { return false }
var srcIndex: Int?
if dstProject != nil, let srcParent = srcProject.parent, !srcParent.isDefault {
srcIndex = srcParent.child.firstIndex(where: { $0 === srcProject })
} else {
srcIndex = sidebarItems.firstIndex(where: { $0 as? Project === srcProject })
}
guard let srcIndex = srcIndex else { return false }
if srcIndex == dstIndex || srcIndex + 1 == dstIndex {
return false
}
// Allow child reordering if parent equal to dst
if let dstProject = dstProject, dstProject === srcProject.parent {
return true
}
if sidebarItems.indices.contains(dstIndex - 1),
let proposedProject = sidebarItems[dstIndex - 1] as? Project,
srcProject.parent === proposedProject.parent
|| (srcProject.isBookmark && proposedProject.parent?.isDefault == true)
|| (srcProject.parent?.isDefault == true && proposedProject.isBookmark)
{
return true
}
if sidebarItems.indices.contains(dstIndex), sidebarItems[dstIndex] as? Project == nil {
return false
}
if sidebarItems.indices.contains(dstIndex + 1),
let proposedProject = sidebarItems[dstIndex + 1] as? Project,
srcProject.parent === proposedProject.parent
|| (srcProject.isBookmark && proposedProject.parent?.isDefault == true)
|| (srcProject.parent?.isDefault == true && proposedProject.isBookmark)
{
return true
}
return false
}
private func saveOrderFor(projects: [Project]) {
var i = 0
for project in projects {
project.settings.priority = i
i += 1
project.saveSettings()
}
}
public func removeTags(notes: [Note]) {
guard let vc = ViewController.shared() else { return }
var allNoteTags: Set = []
for note in vc.notesTableView.getNoteList() {
for tag in note.tags {
if !allNoteTags.contains(tag) {
allNoteTags.insert(tag)
}
}
}
var allRemoveTags = [String]()
for note in notes {
for tag in note.tags {
allRemoveTags.append(tag)
}
}
var remove = [String]()
for tag in allRemoveTags {
if !allNoteTags.contains(tag) {
remove.append(tag)
}
}
removeTags(remove)
}
public func insertTags(note: Note) {
var tags = [String]()
for tag in note.tags {
if !tags.contains(tag) {
tags.append(tag)
}
}
var sTags: Set = []
if let allSidebarTags = sidebarItems?.filter({ ($0 as? FSTag) != nil }).map({ ($0 as? FSTag)!.getFullName() }) {
sTags = Set(allSidebarTags)
}
var insert = [String]()
for tag in tags {
if !sTags.contains(tag) {
insert.append(tag)
}
}
addTags(insert)
}
private func isChangedSidebarItemsState() -> Bool {
let sidebarItems = getSidebarItems()
let selectedItems = selectedSidebarItems
selectedSidebarItems = sidebarItems
if let current = sidebarItems, let selected = selectedItems {
for item in current {
if !selected.contains(where: { $0 === item }) {
return true
}
}
return false
}
return sidebarItems?.count != selectedItems?.count
}
private func isChangedProjectsState() -> Bool {
let sidebarProjects = getSelectedProjects()
let selectedItems = selectedProjects
selectedProjects = sidebarProjects
if let current = sidebarProjects, let selected = selectedItems {
for item in current {
if !selected.contains(where: { $0 === item }) {
return true
}
}
return false
}
return sidebarProjects?.count != selectedItems?.count
}
private func isChangedTagsState() -> Bool {
let sidebarTags = getSidebarTags()
let selectedItems = selectedTags
selectedTags = sidebarTags
if let current = sidebarTags, let selected = selectedTags {
for item in current {
if !selected.contains(item) {
return true
}
}
return false
}
return sidebarTags?.count != selectedItems?.count
}
public func remove(project: Project) {
selectedProjects?.removeAll(where: { $0 === project })
if UserDataService.instance.lastProject?.path == project.url.path {
self.viewDelegate?.cleanSearchAndEditArea()
selectRowIndexes(IndexSet(integer: 0), byExtendingSelection: false)
}
storage.cleanCachedTree(url: project.url)
storage.removeBy(project: project)
guard let vc = ViewController.shared(), vc.isVisibleSidebar() else { return }
if let parent = project.parent, !parent.isDefault {
if let index = parent.child.firstIndex(of: project) {
parent.child.removeAll(where: { $0 == project })
removeItems(at: [index], inParent: parent, withAnimation: .effectFade)
reloadItem(parent)
}
} else {
if let index = sidebarItems?.firstIndex(where: { ($0 as? Project) == project }) {
sidebarItems?.remove(at: index)
removeItems(at: [index], inParent: nil, withAnimation: .effectFade)
}
}
}
public func insertRows(projects: [Project]) {
for project in projects {
insert(project: project)
}
storage.loadProjectRelations()
}
public func removeRows(projects: [Project]) {
// Append and remove childs too if exist
var projects = projects
for item in projects {
let child = item.getChildProjectsByURL()
for childItem in child {
// No project with url
if projects.first(where: { $0.url.path == childItem.url.path }) == nil {
projects.append(childItem)
}
}
}
for project in projects {
// Remove notes from NoteTableView
let notes = project.getNotes()
viewDelegate?.notesTableView.removeRows(notes: notes)
// Remove projects from SidebarOutlineView
remove(project: project)
}
storage.loadProjectRelations()
}
public func insert(project: Project) {
guard let vc = ViewController.shared(),
vc.isVisibleSidebar(),
let lastProjectIndex = vc.sidebarOutlineView.getProjectsSeparatorPosition() else { return }
if let parent = storage.findParent(url: project.url) {
if parent.isDefault {
let offset = lastProjectIndex + countProjects() + 1
vc.sidebarOutlineView.sidebarItems?.insert(project, at: offset)
vc.sidebarOutlineView.insertItems(at: [offset], inParent: nil, withAnimation: .effectFade)
} else {
if parent.child.filter({ $0.url == project.url }).count == 0 {
parent.child.insert(project, at: 0)
vc.sidebarOutlineView.insertItems(at: [0], inParent: parent, withAnimation: .effectFade)
}
vc.sidebarOutlineView.reloadItem(parent)
}
} else {
let offset = lastProjectIndex + countProjects() + 1
vc.sidebarOutlineView.sidebarItems?.insert(project, at: offset)
vc.sidebarOutlineView.insertItems(at: [offset], inParent: nil, withAnimation: .effectFade)
}
viewDelegate?.fsManager?.reloadObservedFolders()
}
public func addRoot() {
let openPanel = NSOpenPanel()
openPanel.allowsMultipleSelection = false
openPanel.canChooseDirectories = true
openPanel.canCreateDirectories = true
openPanel.canChooseFiles = false
openPanel.begin { (result) -> Void in
if result == .OK {
guard let url = openPanel.url else { return }
let bookmarksManager = SandboxBookmark.sharedInstance()
bookmarksManager.store(url: url)
bookmarksManager.save()
if let results = self.storage.insert(url: url, bookmark: true) {
self.insertRows(projects: results)
if let vc = self.viewDelegate {
vc.fsManager?.restart()
}
}
}
}
}
public func getSidebarItems() -> [SidebarItem]? {
var items = [SidebarItem]()
for i in selectedRowIndexes {
if let project = item(atRow: i) as? SidebarItem {
items.append(project)
}
}
return items
}
public func getSidebarProjects() -> [Project]? {
guard let vc = ViewController.shared(), let v = vc.sidebarOutlineView else { return nil }
var projects = [Project]()
for i in v.selectedRowIndexes {
if let si = item(atRow: i) as? SidebarItem, let project = si.project, !project.isVirtual, si.tag == nil {
projects.append(project)
}
}
for i in v.selectedRowIndexes {
if let project = item(atRow: i) as? Project {
projects.append(project)
}
}
for project in projects {
if project.settings.showNestedFoldersContent, !project.isEncrypted, let child = project.getAllChild() {
for item in child {
if !projects.contains(item) {
projects.append(item)
}
}
}
}
if projects.count > 0 {
return projects
}
return nil
}
public func getSidebarTags() -> [String]? {
guard let vc = ViewController.shared(), let v = vc.sidebarOutlineView else { return nil }
var tags = [String]()
for i in v.selectedRowIndexes {
if let tag = (item(atRow: i) as? FSTag)?.getFullName() {
tags.append(tag)
}
}
if tags.count > 0 {
return tags
}
return nil
}
public func getRawSidebarTags() -> [FSTag]? {
guard let vc = ViewController.shared(), let v = vc.sidebarOutlineView else { return nil }
var tags = [FSTag]()
for i in v.selectedRowIndexes {
if let tag = (item(atRow: i) as? FSTag) {
tags.append(tag)
}
}
if tags.count > 0 {
return tags
}
return nil
}
public func getSelectedInlineTags() -> String {
var inlineTags = String()
if let tags = getSidebarTags() {
for tag in tags {
inlineTags += "#\(tag) "
}
}
return inlineTags
}
public func selectNext() {
let i = selectedRow + 1
guard let si = sidebarItems, si.indices.contains(i) else { return }
if let next = si[i] as? SidebarItem {
if next.type == .Separator && next.project == nil {
let j = i + 1
guard let si = sidebarItems, si.indices.contains(j) else { return }
if let next = si[j] as? SidebarItem, next.type != .Separator {
selectRowIndexes([j], byExtendingSelection: false)
return
}
return
}
}
selectRowIndexes([i], byExtendingSelection: false)
}
public func selectPrev() {
let i = selectedRow - 1
guard let si = sidebarItems, si.indices.contains(i) else { return }
if let next = si[i] as? SidebarItem {
if next.type == .Separator && next.project == nil {
let j = i - 1
guard let si = sidebarItems, si.indices.contains(j) else { return }
if let next = si[j] as? SidebarItem, next.type != .Separator {
selectRowIndexes([j], byExtendingSelection: false)
return
}
return
}
}
selectRowIndexes([i], byExtendingSelection: false)
}
public func getSelectedProject() -> Project? {
guard let vc = ViewController.shared(), let v = vc.sidebarOutlineView else { return nil }
if let project = v.item(atRow: v.selectedRow) as? Project {
return project
}
if let sidebarItem = v.item(atRow: v.selectedRow) as? SidebarItem {
if sidebarItem.type == .Inbox {
return vc.storage.getDefault()
}
if let project = sidebarItem.project {
return project
}
}
return nil
}
public func getSelectedProjects() -> [Project]? {
var items = [Project]()
for i in selectedRowIndexes {
if let project = item(atRow: i) as? Project {
items.append(project)
}
}
return items
}
private func getSelectedProjectsIndexes() -> [Int]? {
var items = [Int]()
for i in selectedRowIndexes {
if item(atRow: i) as? Project != nil {
items.append(i)
}
}
return items
}
@objc public func reloadSidebar() {
guard let vc = ViewController.shared() else { return }
vc.fsManager?.reloadObservedFolders()
vc.loadMoveMenu()
let selected = vc.sidebarOutlineView.selectedRow
vc.sidebarOutlineView.sidebarItems = Sidebar().getList()
vc.sidebarOutlineView.reloadData()
vc.sidebarOutlineView.selectRowIndexes([selected], byExtendingSelection: false)
if let project = getSelectedProject(), project.isLocked() {
vc.notesTableView.enableLockedProject()
}
vc.sidebarOutlineView.loadAllTags()
}
public func deselectAllTags() {
guard let items = self.sidebarItems?.filter({($0 as? FSTag) != nil}) else { return }
for item in items {
let i = self.row(forItem: item)
guard i > -1 else { continue }
if let row = self.rowView(atRow: i, makeIfNecessary: false), let cell = row.view(atColumn: 0) as? SidebarCellView {
cell.icon.image = NSImage(named: "sidebar_tag")
}
}
}
public func selectSidebar(type: SidebarItemType) {
if let i = sidebarItems?.firstIndex(where: {($0 as? SidebarItem)?.type == type }) {
selectRowIndexes([i], byExtendingSelection: false)
}
}
public func selectSidebarRoot() {
if let i = sidebarItems?.firstIndex(where: { ($0 as? Project)?.isDefault == true }) {
selectRowIndexes([i], byExtendingSelection: false)
}
}
public func select(note: Note) {
let sidebarItem = sidebarItems?.first(where: {($0 as? SidebarItem)?.project == note.project || $0 as? Project == note.project })
var index = row(forItem: sidebarItem)
if (index == -1) {
var expandQueue = [Project]()
var project = note.project
while let parent = project.parent, isExpandable(parent) {
project = parent
expandQueue.append(project)
}
for item in expandQueue.reversed() {
expandItem(item)
}
index = row(forItem: note.project)
}
if index > -1 {
selectNote = note
scrollRowToVisible(index)
selectRowIndexes([index], byExtendingSelection: false)
return
}
}
public func remove(tag: FSTag) {
if let i = sidebarItems?.firstIndex(where: { ($0 as? FSTag) === tag }) {
self.removeItems(at: [i], inParent: nil, withAnimation: [])
sidebarItems?.remove(at: i)
}
}
public func remove(tagName: String) {
let tags = tagName.components(separatedBy: "/")
guard let parent = tags.first else { return }
if let vc = ViewController.shared(), !vc.isVisibleSidebar() {
return
}
if let tag = sidebarItems?.first(where: {($0 as? FSTag)?.getName() == parent }) as? FSTag {
if tags.count == 1 {
let allTags = ViewController.shared()?.sidebarOutlineView.getAllTags()
let count = allTags?.filter({ $0.starts(with: parent + "/") || $0 == parent }).count ?? 0
if count == 0 {
if let index = sidebarItems?.firstIndex(where: { ($0 as? FSTag)?.getName() == parent }) {
removeItems(at: [index], inParent: nil, withAnimation: [])
sidebarItems?.remove(at: index)
}
}
} else if var foundTag = tag.find(name: tagName) {
while let parent = foundTag.getParent() {
if let i = parent.indexOf(child: foundTag) {
removeItems(at: [i], inParent: parent, withAnimation: [])
parent.remove(by: i)
}
if
parent.getParent() == nil
&& parent.child.count == 0,
let i = sidebarItems?.firstIndex(where: { ($0 as? FSTag)?.getName() == parent.getName() })
{
if isAllowTagRemoving(parent.getName()) {
removeItems(at: [i], inParent: nil, withAnimation: [])
sidebarItems?.remove(at: i)
}
break
}
foundTag = parent
}
}
}
}
public func addTags(_ tags: [String], shouldUnloadOld: Bool = false) {
guard tags.count > 0 else {
unloadAllTags()
return
}
beginUpdates()
if shouldUnloadOld {
unloadAllTags()
}
for tag in tags {
addTag(tag: tag)
}
endUpdates()
}
public func removeTags(_ tags: [String]) {
var removeTags = [String]()
for tag in tags {
if isAllowTagRemoving(tag) {
removeTags.append(tag)
}
}
beginUpdates()
for tag in removeTags {
remove(tagName: tag)
}
endUpdates()
}
public func isAllowTagRemoving(_ name: String) -> Bool {
let tags = getAllTags()
var allow = true
for tag in tags {
if tag.starts(with: name + "/") || tag == name {
allow = false
}
}
return allow
}
public func reloadTags() {
if UserDefaultsManagement.inlineTags {
loadAllTags()
}
}
public func unloadAllTags() {
if let tags = sidebarItems?.filter({ ($0 as? FSTag) != nil && ($0 as? FSTag)?.getParent()
== nil }) as? [FSTag] {
beginUpdates()
for tag in tags {
remove(tag: tag)
}
endUpdates()
}
}
public func getAllTags() -> [String] {
var tags: Set = []
var projects: [Project]? = getSidebarProjects()
let selectedItem = item(atRow: selectedRow) as? SidebarItem
if selectedItem?.type == .All || projects == nil {
projects = storage.getProjects().filter({ !$0.isTrash && $0.settings.showInCommon })
}
if let projects = projects {
for project in projects {
let projectTags = project.getAllTags()
for tag in projectTags {
if !tags.contains(tag) {
tags.insert(tag)
}
}
}
}
return Array(tags)
}
public func loadAllTags() {
let tags = getAllTags()
addTags(tags.sorted(), shouldUnloadOld: true)
}
public func select(tag: String) {
let fullTags = tag.split(separator: "/").map(String.init);
var items = sidebarItems;
var tagDepth: Int = 0
var selectedIndexes = getSelectedProjectsIndexes() ?? [tagDepth]
let currentNote = viewDelegate?.editor.note
selectNote = currentNote
for tagIndex in 0.. 1 else { return }
while subtags.count > 0 {
subtags = Array(subtags.dropFirst())
tag.addChild(name: subtags.joined(separator: "/"), completion: { (tagItem, isExist, position) in
tag = tagItem
if !isExist {
insertItems(at: [position], inParent: tagItem.getParent(), withAnimation: [])
}
})
guard subtags.count > 1 else { break }
}
return
}
let rootTag = FSTag(name: tag)
let position = getRootTagPosition(for: rootTag)
sidebarItems?.insert(rootTag, at: position)
self.insertItems(at: [position], inParent: nil, withAnimation: [])
}
public func getRootTagPosition(for tag: FSTag) -> Int {
guard let offset = sidebarItems?.firstIndex(where: { ($0 as? FSTag) != nil }) else {
return sidebarItems?.count ?? 0
}
guard var tags = sidebarItems?.filter({ $0 as? FSTag != nil }) as? [FSTag] else {
return sidebarItems?.count ?? 0
}
tags.append(tag)
let sorted = tags.sorted(by: { $0.name.lowercased() < $1.name.lowercased() })
if let index = sorted.firstIndex(where: { $0 === tag }) {
return index + offset
}
return sidebarItems?.count ?? 0
}
public func getTagsSeparatorPosition() -> Int? {
return sidebarItems?.firstIndex(where: { ($0 as? SidebarItem)?.type == .Separator && ($0 as? SidebarItem)?.name == "tags" })
}
public func getProjectsSeparatorPosition() -> Int? {
return sidebarItems?.firstIndex(where: { ($0 as? SidebarItem)?.type == .Separator && ($0 as? SidebarItem)?.name == "projects" })
}
public func countProjects() -> Int {
return sidebarItems?.filter({ ($0 as? Project) != nil }).count ?? 0
}
public func deleteRoot(tag: String) {
guard let vc = ViewController.shared(), vc.isVisibleSidebar() else { return }
let subtags = tag.components(separatedBy: "/")
if let sidebarIndex = sidebarItems?.firstIndex(where: { ($0 as? FSTag)?.name == subtags.first }) {
sidebarItems?.remove(at: sidebarIndex)
removeItems(at: [sidebarIndex], inParent: nil, withAnimation: [])
}
}
public func remove(tags: [String], from notes: [Note]) {
guard let notesTableView = viewDelegate?.notesTableView else { return }
for note in notes {
for tagName in tags.reversed() {
note.delete(tag: "#\(tagName)")
note.tags.removeAll(where: { $0 == tagName })
_ = note.scanContentTags()
}
DispatchQueue.main.async {
notesTableView.reloadRow(note: note)
}
}
if let vc = ViewController.shared(), vc.isVisibleSidebar() {
beginUpdates()
for index in selectedRowIndexes.reversed() {
if let tag = item(atRow: index) as? FSTag {
if let parentTag = tag.getParent() {
if let childIndex = tag.getParent()?.child.firstIndex(where: { $0 === tag }) {
tag.parent?.removeChild(tag: tag)
removeItems(at: [childIndex], inParent: parentTag, withAnimation: [])
}
} else if let sidebarIndex = sidebarItems?.firstIndex(where: { ($0 as? FSTag) === tag }) {
sidebarItems?.remove(at: sidebarIndex)
removeItems(at: [sidebarIndex], inParent: nil, withAnimation: [])
}
}
}
endUpdates()
}
viewDelegate?.editor.clear()
}
public func rename(tags: [FSTag], name: String) {
guard let notesTableView = viewDelegate?.notesTableView else { return }
let notes = notesTableView.getNoteList()
let originalName = name.starts(with: "#") ? String(name.dropFirst()) : name
let name = name.starts(with: "#") ? name : "#\(name)"
var insertTags = [String]()
var deleteTags = [String]()
// get all root deleted tags and all inserted from roots combined with renamed
for tag in tags {
let tagNameOriginal = tag.getFullName()
var fullName = tagNameOriginal
let firstLevel = fullName.components(separatedBy: "/").first ?? fullName
deleteTags.append(fullName)
let allTags = getAllTags()
// select all started from "#search/level/" or equal "#search/level"
let related = allTags.filter({ $0.starts(with: fullName + "/") || $0 == fullName })
// select all started i.e. "#search/yyy" but NOT "#search/level/" and "#search/level"
let relatedAdditional = allTags.filter({
$0.starts(with: firstLevel + "/")
&& !$0.starts(with: fullName + "/")
&& $0 != fullName
})
// rename related
for item in related {
fullName = item
guard let range = fullName.range(of: tagNameOriginal) else { continue }
if range.lowerBound.utf16Offset(in: tagNameOriginal) == 0 {
fullName.replaceSubrange(range, with: originalName)
}
insertTags.append(fullName)
}
// and add additional
for item in relatedAdditional {
insertTags.append(item)
}
}
// rename tags in notes
for note in notes {
for tag in tags {
// rename and rescan tags ended with empty space separators or slash and skip with chars
let tagName = tag.getFullName()
note.replace(tag: "#\(tagName)", with: name)
note.tags.removeAll(where: { $0 == tagName })
_ = note.scanContentTags()
// reload view in notes list
DispatchQueue.main.async {
notesTableView.reloadRow(note: note)
}
}
}
// update view
beginUpdates()
for tag in deleteTags {
deleteRoot(tag: tag)
}
for tag in insertTags {
addTag(tag: tag)
}
endUpdates()
// select inserted
if let tag = insertTags.first?.components(separatedBy: "/").first {
if let tag = sidebarItems?.first(where: { ($0 as? FSTag)?.name == tag }) {
let index = row(forItem: tag)
scrollRowToVisible(index)
selectRowIndexes([index], byExtendingSelection: true)
}
}
}
public func deselectAllRows() {
UserDefaultsManagement.lastSidebarItem = nil
UserDefaultsManagement.lastProjectURL = nil
deselectAll(nil)
}
public func getNotesProject() -> Project? {
let item = sidebarItems?.first(where: {
($0 as? SidebarItem)?.type == .All
}) as? SidebarItem
return item?.project
}
public func getOrCreateProject(name: String) -> Project? {
guard let project = Storage.shared().getDefault() else { return nil }
let url = project.url.appendingPathComponent(name, isDirectory: true)
if let exist = Storage.shared().getProjectBy(url: url) {
DispatchQueue.main.async {
self.focus(on: exist)
}
return exist
}
return createProject(with: name)
}
public func createProject(in project: Project? = nil, with name: String) -> Project? {
guard let vc = ViewController.shared(),
let project = project ?? Storage.shared().getDefault() else { return nil }
var insertedProject: Project?
do {
let projectURL = project.url.appendingPathComponent(name, isDirectory: true)
try FileManager.default.createDirectory(at: projectURL, withIntermediateDirectories: false, attributes: nil)
guard let inserted = project.storage.insert(url: projectURL) else { return nil }
insertedProject = inserted.first
// Important before main queue (Disables the fake move event handler for notes)
vc.fsManager?.reloadObservedFolders()
DispatchQueue.main.async {
vc.sidebarOutlineView.insertRows(projects: inserted)
guard let newProject = inserted.first else { return }
self.focus(on: newProject)
print("sidebar table")
}
} catch {
DispatchQueue.main.async {
let alert = NSAlert()
alert.messageText = error.localizedDescription
alert.runModal()
}
}
return insertedProject
}
public func focus(on project: Project) {
guard let vc = ViewController.shared() else { return }
let expand = project.parent
vc.sidebarOutlineView.expandItem(expand)
let row = vc.sidebarOutlineView.row(forItem: project)
guard row != -1 else { return }
vc.sidebarOutlineView.selectRowIndexes(
IndexSet(integer: row),
byExtendingSelection: false
)
vc.sidebarOutlineView.scrollRowToVisible(row)
}
}
================================================
FILE: FSNotes/View/SidebarSplitView.swift
================================================
//
// SidebarSplitView.swift
// FSNotes
//
// Created by Oleksandr Glushchenko on 9/29/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
class SidebarSplitView: NSSplitView {
override var dividerColor: NSColor {
return NSColor.init(named: "divider")!
}
}
================================================
FILE: FSNotes/View/SidebarTableRowView.swift
================================================
//
// SidebarTableRowView.swift
// FSNotes
//
// Created by Oleksandr Glushchenko on 4/11/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
class SidebarTableRowView: NSTableRowView {
}
================================================
FILE: FSNotes/View/TitleBarView.swift
================================================
//
// TitleBarView.swift
// FSNotes
//
// Created by BUDDAx2 on 10/27/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
class TitleBarView: NSView {
var onMouseEnteredClosure: (()->())?
var onMouseExitedClosure: (()->())?
override func awakeFromNib() {
addTrackingArea(NSTrackingArea(rect: bounds, options: [.activeAlways, .mouseEnteredAndExited], owner: self, userInfo: nil))
}
override func layout() {
super.layout()
self.trackingAreas.forEach { [weak self] area in
self?.removeTrackingArea(area)
}
addTrackingArea(NSTrackingArea(rect: bounds, options: [.activeAlways, .mouseEnteredAndExited], owner: self, userInfo: nil))
}
override func mouseEntered(with event: NSEvent) {
onMouseEnteredClosure?()
}
override func mouseExited(with event: NSEvent) {
onMouseExitedClosure?()
}
override func mouseDown(with event: NSEvent) {
if event.clickCount == 2, let actionOnDoubleClick = UserDefaults.standard.object(forKey: "AppleActionOnDoubleClick") as? String {
switch actionOnDoubleClick {
case "Maximize":
self.window?.windowController?.maximizeWindow()
case "Minimize":
self.window?.performMiniaturize(nil)
default:
break
}
}
}
}
================================================
FILE: FSNotes/View/TitleTextField.swift
================================================
//
// TitleTextField.swift
// FSNotes
//
// Created by Олександр Глущенко on 5/10/19.
// Copyright © 2019 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
import Carbon.HIToolbox
class TitleTextField: NSTextField {
public var restoreResponder: NSResponder?
override func performKeyEquivalent(with event: NSEvent) -> Bool {
if event.modifierFlags.contains(.command)
&& event.characters?.unicodeScalars.first == "c"
&& !event.modifierFlags.contains(.shift)
&& !event.modifierFlags.contains(.control)
&& !event.modifierFlags.contains(.option) {
let pasteboard = NSPasteboard.general
pasteboard.declareTypes([NSPasteboard.PasteboardType.string], owner: nil)
pasteboard.setString(self.stringValue, forType: NSPasteboard.PasteboardType.string)
}
return super.performKeyEquivalent(with: event)
}
override func becomeFirstResponder() -> Bool {
if let vc = ViewController.shared(),
let note = vc.editor.note {
stringValue = note.getFileName()
}
return super.becomeFirstResponder()
}
override func textDidEndEditing(_ notification: Notification) {
guard stringValue.count > 0,
let vc = ViewController.shared(),
let note = vc.editor.note
else { return }
let currentTitle = stringValue
let currentName = note.getFileName()
defer {
updateNotesTableView()
editModeOff()
}
if currentName != currentTitle {
rename(currentTitle: currentTitle, note: note)
return
}
vc.updateTitle(note: note)
self.resignFirstResponder()
updateNotesTableView()
vc.titleLabel.isEditable = false
vc.titleLabel.isEnabled = false
}
public func rename(currentTitle: String, note: Note) {
guard let vc = ViewController.shared() else { return }
_ = vc.lockUnlocked(notes: [note])
let currentName = note.getFileName()
let ext = note.url.pathExtension
let fileName =
currentTitle
.trimmingCharacters(in: CharacterSet.whitespaces)
.replacingOccurrences(of: ":", with: "")
.replacingOccurrences(of: "/", with: "")
let dst = note.project.url
.appendingPathComponent(fileName)
.appendingPathExtension(ext)
let hasCaseSensitiveDiffOnly = currentName.lowercased() == fileName.lowercased()
if !FileManager.default.fileExists(atPath: dst.path) || hasCaseSensitiveDiffOnly {
_ = note.move(to: dst, forceRewrite: hasCaseSensitiveDiffOnly)
vc.updateTitle(note: note)
updateNotesTableView()
vc.reSort(note: note)
} else {
vc.updateTitle(note: note)
self.resignFirstResponder()
updateNotesTableView()
vc.titleLabel.isEditable = false
vc.titleLabel.isEnabled = false
let alert = NSAlert()
let informativeText = NSLocalizedString("Note with name \"%@\" already exists in selected directory.", comment: "")
alert.alertStyle = .critical
alert.informativeText = String(format: informativeText, currentTitle)
alert.runModal()
}
}
public func editModeOn() {
self.isEnabled = true
self.isEditable = true
MainWindowController.shared()?.makeFirstResponder(self)
}
public func editModeOff() {
self.isEnabled = false
self.isEditable = false
guard let vc = ViewController.shared(),
let note = vc.editor.note else { return }
vc.updateTitle(note: note)
}
public func updateNotesTableView() {
guard let vc = ViewController.shared(), let note = vc.editor.note else { return }
if (note.container == .encryptedTextPack && !note.isUnlocked()) || !note.project.settings.isFirstLineAsTitle() {
vc.notesTableView.reloadRow(note: note)
}
if let responder = restoreResponder {
window?.makeFirstResponder(responder)
}
}
}
================================================
FILE: FSNotes/View/VerticallyAlignedTextFieldCell.swift
================================================
//
// VerticallyAlignedTextFieldCell.swift
// FSNotes
//
// Created by Олександр Глущенко on 03.05.2020.
// Copyright © 2020 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
class VerticallyAlignedTextFieldCell: NSTextFieldCell {
override func drawingRect(forBounds rect: NSRect) -> NSRect {
let newRect = NSRect(x: 0, y: (rect.size.height - 22) / 2, width: rect.size.width, height: 22)
return super.drawingRect(forBounds: newRect)
}
}
================================================
FILE: FSNotes/ViewController+Git.swift
================================================
//
// ViewController+Git.swift
// FSNotes
//
// Created by Олександр Глущенко on 9/10/19.
// Copyright © 2019 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
import Git
import Cgit2
extension EditorViewController {
@IBAction func saveRevision(_ sender: NSMenuItem) {
guard let gitProject = getGitProject() else {
let alert = NSAlert()
alert.alertStyle = .critical
alert.informativeText = NSLocalizedString("Please init git repository before (Preferences -> Git -> Init/commit)", comment: "")
alert.messageText = NSLocalizedString("Repository not found", comment: "")
alert.runModal()
return
}
guard let window = self.view.window else { return }
if UserDefaultsManagement.askCommitMessage {
let field = NSTextField(frame: NSRect(x: 0, y: 0, width: 290, height: 60))
if let lastMessage = UserDefaultsManagement.lastCommitMessage {
field.stringValue = lastMessage
}
let alert = NSAlert()
alert.messageText = NSLocalizedString("Commit message:", comment: "")
alert.accessoryView = field
alert.alertStyle = .informational
alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
alert.addButton(withTitle: NSLocalizedString("Cancel", comment: ""))
alert.beginSheetModal(for: window) { (returnCode: NSApplication.ModalResponse) -> Void in
if returnCode == NSApplication.ModalResponse.alertFirstButtonReturn {
let commitMessage: String? = field.stringValue.count > 0 ? field.stringValue : nil
if field.stringValue.count > 0 {
UserDefaultsManagement.lastCommitMessage = commitMessage
}
self.saveRevision(project: gitProject, commitMessage: commitMessage)
}
}
field.becomeFirstResponder()
return
}
saveRevision(project: gitProject, commitMessage: nil)
}
private func saveRevision(project: Project, commitMessage: String? = nil) {
guard let window = self.view.window else { return }
ViewController.gitQueue.addOperation({
ViewController.gitQueueOperationDate = Date()
defer {
ViewController.gitQueueOperationDate = nil
}
do {
try project.saveRevision(commitMessage: commitMessage)
} catch GitError.noAddedFiles {
// pass
} catch {
var message = String()
if let error = error as? GitError {
message = error.associatedValue()
} else {
message = error.localizedDescription
}
DispatchQueue.main.async {
let alert = NSAlert()
alert.alertStyle = .critical
alert.informativeText = message
alert.messageText = NSLocalizedString("Git error", comment: "")
alert.beginSheetModal(for: window) { (returnCode: NSApplication.ModalResponse) -> Void in }
}
}
})
}
@IBAction func checkoutRevision(_ sender: NSMenuItem) {
guard let vc = ViewController.shared() else { return }
guard let commit = sender.representedObject as? Commit else { return }
guard let note = vcEditor?.note else { return }
if vc.prevCommit == nil {
saveRevision(project: note.project, commitMessage: "Auto save on history checkout")
}
vc.prevCommit = commit
note.checkout(commit: commit)
_ = note.reload()
NotesTextProcessor.highlight(attributedString: note.content)
reloadAllOpenedWindows(note: note)
ViewController.shared()?.notesTableView.reloadRow(note: note)
vcEditor?.scanTagsAndAutoRename()
}
@IBAction private func makeFullSnapshot(_ sender: Any) {
let cal = Calendar.current
let hour = cal.component(.hour, from: Date())
let minute = cal.component(.minute, from: Date())
if let lastSnapshot = self.lastSnapshot {
if minute == lastSnapshot {
return
} else {
self.lastSnapshot = nil
}
}
guard UserDefaultsManagement.snapshotsInterval != 0 && (
hour == UserDefaultsManagement.snapshotsInterval || (
hour != 0 && hour % UserDefaultsManagement.snapshotsInterval == 0
)
) else { return }
guard UserDefaultsManagement.snapshotsIntervalMinutes == minute else { return }
lastSnapshot = minute
ViewController.gitQueue.addOperation({
ViewController.gitQueueOperationDate = Date()
defer {
ViewController.gitQueueOperationDate = nil
}
let storage = Storage.shared()
guard let projects = storage.getGitProjects() else { return }
for project in projects {
do {
if project.hasRepository() {
try project.commit()
try project.pull()
try project.push()
}
} catch {
print(error)
}
}
})
}
@IBAction private func pull(_ sender: Any) {
// Restart queue if operation stucked more then 2 minutes
if let date = ViewController.gitQueueOperationDate {
let diff = Int(Date().timeIntervalSince1970) - Int(date.timeIntervalSince1970)
let isBusy = ViewController.gitQueueBusy
if diff > 120 && !isBusy {
ViewController.gitQueue = OperationQueue()
ViewController.gitQueue.maxConcurrentOperationCount = 1
print("Git queue restart")
} else {
print("Git pull skipped")
return
}
}
ViewController.gitQueue.addOperation({
ViewController.gitQueueOperationDate = Date()
defer {
ViewController.gitQueueOperationDate = nil
}
Storage.shared().pullAll()
})
}
public func scheduleSnapshots() {
guard !UserDefaultsManagement.backupManually else { return }
DispatchQueue.main.async {
self.snapshotsTimer.invalidate()
self.snapshotsTimer = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(self.makeFullSnapshot), userInfo: nil, repeats: true)
}
}
public func schedulePull() {
guard !UserDefaultsManagement.backupManually else { return }
let interval = UserDefaultsManagement.pullInterval
pullTimer.invalidate()
pullTimer = Timer.scheduledTimer(timeInterval: TimeInterval(interval), target: self, selector: #selector(pull), userInfo: nil, repeats: true)
}
public func stopPull() {
pullTimer.invalidate()
}
public func getGitProject() -> Project? {
guard let vc = ViewController.shared() else { return nil }
if let project = vc.getSelectedNote()?.project.getGitProject() {
return project
}
if let project = vc.sidebarOutlineView.getSelectedProject()?.getGitProject() {
return project
}
return Storage.shared().getDefault()?.getGitProject()
}
}
================================================
FILE: FSNotes/ViewController+Menu.swift
================================================
//
// ViewController+Menu.swift
// FSNotes
//
// Created by Oleksandr Hlushchenko on 16.12.2025.
// Copyright © 2025 Oleksandr Hlushchenko. All rights reserved.
//
import AppKit
extension ViewController {
func processFileMenuItems(_ menuItem: NSMenuItem, menuId: String) -> Bool {
// Submenu
if menuItem.menu?.identifier?.rawValue == "fileMenu.move" ||
menuItem.menu?.identifier?.rawValue == "fileMenu.history" {
return true
}
guard let vc = ViewController.shared(),
let evc = NSApplication.shared.keyWindow?.contentViewController as? EditorViewController,
let id = menuItem.identifier?.rawValue else { return false }
// Sidebar
let tags = vc.sidebarOutlineView.getSidebarTags()
let projects = vc.sidebarOutlineView.getSelectedProjects()
let projectSelected = projects?.isEmpty == false
let tagSelected = tags?.isEmpty == false
let isFirstSidebar = evc.view.window?.firstResponder?.isKind(of: SidebarOutlineView.self) == true
let isInbox = vc.sidebarOutlineView.getSidebarItems()?.first?.type == .Inbox
let isTrash = vc.sidebarOutlineView.getSidebarItems()?.first?.type == .Trash
// Notes
let isFirstResponder = evc.view.window?.firstResponder?.isKind(of: NotesTableView.self) == true
let isFirstEditor = evc.view.window?.firstResponder?.isKind(of: EditTextView.self) == true
let isOpenedWindow = NSApplication.shared.keyWindow?.contentViewController?.isKind(of: NoteViewController.self) == true
let notes = vc.getSelectedNotes()
let greaterThanZero = notes?.isEmpty == false
let isOne = notes?.count == 1
func hasEncrypted(notes: [Note]? = nil) -> Bool {
guard let notes = notes else { return false }
return notes.contains { $0.isEncrypted() && !$0.project.isEncrypted }
}
switch id {
case "\(menuId).close":
menuItem.title = NSLocalizedString("Close", comment: "File Menu")
return true
case "\(menuId).import":
menuItem.title = NSLocalizedString("Import", comment: "File Menu")
return true
case "\(menuId).attach":
menuItem.title = NSLocalizedString("Add External Folder...", comment: "Menu Library")
return true
case "\(menuId).backup":
var title = NSLocalizedString("Inbox", comment: "")
if let gitProject = vc.getGitProject() {
title = gitProject.label
if gitProject.isDefault {
title = NSLocalizedString("Inbox", comment: "")
}
menuItem.title = String(format: NSLocalizedString("Commit & Push “%@”", comment: "Menu Library"), title)
return true
}
return false
case "\(menuId).new":
menuItem.title = NSLocalizedString("New Note", comment: "File Menu")
return true
case "\(menuId).newInNewWindow":
menuItem.title = NSLocalizedString("New Note in New Window", comment: "File Menu")
return true
case "\(menuId).createFolder":
menuItem.title = NSLocalizedString("New Folder", comment: "Menu Library")
return !isTrash
case "\(menuId).searchAndCreate":
menuItem.title = NSLocalizedString("Search and Create", comment: "File Menu")
return true
case "\(menuId).open":
menuItem.title = NSLocalizedString("Open Note in New Window", comment: "File Menu")
return greaterThanZero
case "\(menuId).duplicate":
menuItem.title = NSLocalizedString("Duplicate", comment: "File Menu")
return greaterThanZero && (isFirstResponder || isFirstEditor)
case "\(menuId).rename":
// sidebar
if isFirstSidebar {
if tagSelected {
menuItem.title = NSLocalizedString("Rename Tag", comment: "Menu Library")
} else {
menuItem.title = NSLocalizedString("Rename Folder", comment: "Menu Library")
}
return projectSelected || tagSelected
}
menuItem.title = NSLocalizedString("Rename", comment: "File Menu")
return isOne && isFirstResponder || (isFirstEditor && !isOpenedWindow)
case "\(menuId).delete":
menuItem.title = NSLocalizedString("Delete", comment: "File Menu")
return greaterThanZero && isFirstResponder
case "\(menuId).forceDelete":
menuItem.title = NSLocalizedString("Force Delete", comment: "File Menu")
return greaterThanZero && isFirstResponder
case "\(menuId).togglePin":
if let note = notes?.first, note.isPinned {
menuItem.title = NSLocalizedString("Unpin", comment: "File Menu")
} else {
menuItem.title = NSLocalizedString("Pin", comment: "File Menu")
}
return greaterThanZero
case "\(menuId).decrypt":
// sidebar
if isFirstSidebar {
menuItem.title = NSLocalizedString("Decrypt Folder", comment: "Menu Library")
if let project = projects?.first, !project.isTrash, !project.isDefault, !project.isVirtual, project.isEncrypted {
return true
}
return false
}
menuItem.title = NSLocalizedString("Decrypt", comment: "File Menu")
return greaterThanZero && hasEncrypted(notes: notes)
case "\(menuId).toggleLock":
// sidebar
if isFirstSidebar {
if let project = projects?.first, !project.isTrash, project.isLocked() {
menuItem.title = NSLocalizedString("Unlock Folder", comment: "")
} else {
menuItem.title = NSLocalizedString("Lock Folder", comment: "Menu Library")
}
return projectSelected
}
if let note = notes?.first, note.isEncryptedAndLocked() {
menuItem.title = NSLocalizedString("Unlock", comment: "File Menu")
} else {
menuItem.title = NSLocalizedString("Lock", comment: "File Menu")
}
return greaterThanZero && (isFirstResponder || isOpenedWindow || isFirstEditor)
case "\(menuId).external":
menuItem.title = NSLocalizedString("Open External", comment: "File Menu")
return greaterThanZero
case "\(menuId).reveal":
if isFirstSidebar {
menuItem.title = NSLocalizedString("Reveal in Finder", comment: "Menu Library")
return projectSelected || isInbox
}
menuItem.title = NSLocalizedString("Reveal in Finder", comment: "File Menu")
return greaterThanZero && (isFirstResponder || isOpenedWindow || isFirstEditor)
case "\(menuId).date":
menuItem.title = NSLocalizedString("Change Creation Date", comment: "File Menu")
return greaterThanZero && (isFirstResponder || isOpenedWindow || isFirstEditor)
case "\(menuId).toggleContainer":
if let note = notes?.first, note.container == .none {
menuItem.title = NSLocalizedString("Convert to TextBundle", comment: "")
} else {
menuItem.title = NSLocalizedString("Convert to Plain", comment: "")
}
return greaterThanZero && !hasEncrypted(notes: notes) && (isFirstResponder || isOpenedWindow)
case "\(menuId).move":
menuItem.title = NSLocalizedString("Move", comment: "File Menu")
return greaterThanZero && (isFirstResponder || isOpenedWindow || isFirstEditor)
case "\(menuId).history":
menuItem.title = NSLocalizedString("History", comment: "File Menu")
if let note = notes?.first {
return isOne && (isFirstResponder || isOpenedWindow || isFirstEditor) && note.project.hasCommitsDiffsCache()
}
case "\(menuId).print":
menuItem.title = NSLocalizedString("Print", comment: "File Menu")
return isOne && (isFirstResponder || isOpenedWindow || isFirstEditor)
default:
break
}
return false
}
func processShareMenuItems(_ menuItem: NSMenuItem, menuId: String) -> Bool {
guard let vc = ViewController.shared(),
let evc = NSApplication.shared.keyWindow?.contentViewController as? EditorViewController,
let id = menuItem.identifier?.rawValue else { return false }
let isFirstResponder = evc.view.window?.firstResponder?.isKind(of: NotesTableView.self) == true
let isFirstEditor = evc.view.window?.firstResponder?.isKind(of: EditTextView.self) == true
let isOpenedWindow = NSApplication.shared.keyWindow?.contentViewController?.isKind(of: NoteViewController.self) == true
let notes = vc.getSelectedNotes()
let isOne = notes?.count == 1
switch id {
case "\(menuId).copyURL":
menuItem.title = NSLocalizedString("Copy URL", comment: "File Menu")
return isOne && (isFirstResponder || isOpenedWindow || isFirstEditor)
case "\(menuId).copyTitle":
menuItem.title = NSLocalizedString("Copy Title", comment: "File Menu")
return isOne && (isFirstResponder || isOpenedWindow || isFirstEditor)
case "\(menuId).uploadOverSSH":
if let note = notes?.first, note.uploadPath != nil || note.apiId != nil {
menuItem.title = NSLocalizedString("Update Web Page", comment: "File Menu")
} else {
menuItem.title = NSLocalizedString("Create Web Page", comment: "File Menu")
}
return isOne && (isFirstResponder || isOpenedWindow || isFirstEditor)
case "\(menuId).removeOverSSH":
menuItem.title = NSLocalizedString("Delete Web Page", comment: "File Menu")
if let note = notes?.first {
return (isFirstResponder || isOpenedWindow || isFirstEditor) && isOne && !note.isEncrypted() && (note.uploadPath != nil || note.apiId != nil)
}
default:
return false
}
return false
}
func processLibraryMenuItems(_ menuItem: NSMenuItem, menuId: String) -> Bool {
guard let vc = ViewController.shared(),
let id = menuItem.identifier?.rawValue else { return false }
let tags = vc.sidebarOutlineView.getSidebarTags()
let projects = vc.sidebarOutlineView.getSelectedProjects()
let projectSelected = projects?.isEmpty == false
let tagSelected = tags?.isEmpty == false
let isFirstResponder = view.window?.firstResponder?.isKind(of: SidebarOutlineView.self) == true
let isTrash = vc.sidebarOutlineView.getSidebarItems()?.first?.type == .Trash
let isInbox = vc.sidebarOutlineView.getSidebarItems()?.first?.type == .Inbox
let isSystem = vc.sidebarOutlineView.getSidebarItems()?.first?.isSystem() == true
switch id {
case "\(menuId).create":
menuItem.title = NSLocalizedString("Create Folder", comment: "Menu Library")
return !isTrash
case "\(menuId).rename":
if tagSelected {
menuItem.title = NSLocalizedString("Rename Tag", comment: "Menu Library")
} else {
menuItem.title = NSLocalizedString("Rename Folder", comment: "Menu Library")
}
return isFirstResponder && (projectSelected || tagSelected)
case "\(menuId).delete":
if let project = projects?.first, project.isBookmark {
menuItem.title = NSLocalizedString("Unlink External Folder", comment: "Menu Library")
} else if tagSelected {
menuItem.title = NSLocalizedString("Delete Tag", comment: "Menu Library")
} else {
menuItem.title = NSLocalizedString("Delete Folder", comment: "Menu Library")
}
return isFirstResponder && (projectSelected || tagSelected)
case "\(menuId).decrypt":
menuItem.title = NSLocalizedString("Decrypt Folder", comment: "Menu Library")
if let project = projects?.first, !project.isTrash, !project.isDefault, !project.isVirtual, project.isEncrypted {
return isFirstResponder
}
case "\(menuId).toggleLock":
if let project = projects?.first, !project.isTrash, project.isLocked() {
menuItem.title = NSLocalizedString("Unlock Folder", comment: "")
} else {
menuItem.title = NSLocalizedString("Lock Folder", comment: "Menu Library")
}
return isFirstResponder && projectSelected
case "\(menuId).reveal":
menuItem.title = NSLocalizedString("Reveal in Finder", comment: "Menu Library")
return isFirstResponder && (projectSelected || isInbox)
case "\(menuId).options":
menuItem.title = NSLocalizedString("Show Options", comment: "Menu Library")
return isFirstResponder && (projectSelected || isSystem)
default:
break
}
return false
}
func loadMoveMenu() {
guard let vc = ViewController.shared(), let note = vc.notesTableView.getSelectedNote() else { return }
let moveTitle = NSLocalizedString("Move", comment: "Menu")
if let prevMenu = noteMenu.item(withTitle: moveTitle) {
noteMenu.removeItem(prevMenu)
}
let moveMenuItem = NSMenuItem()
moveMenuItem.title = NSLocalizedString("Move", comment: "Menu")
moveMenuItem.image = NSImage(systemSymbolName: "move.3d", accessibilityDescription: nil)
noteMenu.addItem(moveMenuItem)
let moveMenu = NSMenu()
moveMenu.identifier = NSUserInterfaceItemIdentifier("fileMenu.move")
if UserDefaultsManagement.inlineTags, let tagsMenu = noteMenu.item(withTitle: NSLocalizedString("Tags", comment: "")) {
noteMenu.removeItem(tagsMenu)
}
if !note.isTrash() {
let trashMenu = NSMenuItem()
trashMenu.title = NSLocalizedString("Trash", comment: "Sidebar label")
trashMenu.action = #selector(vc.notesTableView.delete(_:))
trashMenu.tag = 555
moveMenu.addItem(trashMenu)
moveMenu.addItem(NSMenuItem.separator())
}
let projects = storage.getSortedProjects()
for item in projects {
if note.project == item || item.isTrash {
continue
}
let menuItem = NSMenuItem()
menuItem.title = item.getNestedLabel()
menuItem.representedObject = item
menuItem.action = #selector(vc.moveNote(_:))
moveMenu.addItem(menuItem)
}
noteMenu.setSubmenu(moveMenu, for: moveMenuItem)
loadHistory()
}
public func loadHistory() {
guard let vc = ViewController.shared(),
let notes = vc.notesTableView.getSelectedNotes(),
let note = notes.first
else { return }
let title = NSLocalizedString("History", comment: "")
let historyMenu = noteMenu.item(withTitle: title)
historyMenu?.submenu?.removeAllItems()
historyMenu?.isEnabled = false
historyMenu?.isHidden = !note.project.hasCommitsDiffsCache()
guard notes.count == 0x01 else { return }
DispatchQueue.global().async {
let commits = note.getCommits()
DispatchQueue.main.async {
guard commits.count > 0 else {
historyMenu?.isEnabled = false
return
}
for commit in commits {
let menuItem = NSMenuItem()
menuItem.title = commit.getDate()
menuItem.representedObject = commit
menuItem.action = #selector(vc.checkoutRevision(_:))
historyMenu?.submenu?.addItem(menuItem)
}
historyMenu?.isEnabled = true
}
}
}
}
================================================
FILE: FSNotes/ViewController+Print.swift
================================================
//
// ViewController+Print.swift
// FSNotes
//
// Created by Oleksandr Glushchenko on 2/15/19.
// Copyright © 2019 Oleksandr Glushchenko. All rights reserved.
//
import WebKit
extension EditorViewController {
public func printMarkdownPreview() {
guard let note = vcEditor?.note else { return }
let printDir = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("Print")
try? FileManager.default.removeItem(at: printDir)
guard let indexURL = MPreviewView.buildPage(for: note, at: printDir, print: true) else { return }
if #available(macOS 11.0, *) {
let pdfCreator = Printer(indexURL: indexURL)
pdfCreator.printWeb()
} else {
legacyPrint(indexURL: indexURL)
}
}
@available(*, deprecated, message: "Remove after macOS 10.15 is no longer supported")
public func legacyPrint(indexURL: URL) {
guard let vc = ViewController.shared() else { return }
vc.printerLegacy = PrinterLegacy(indexURL: indexURL)
vc.printerLegacy?.printWeb()
}
}
================================================
FILE: FSNotes/ViewController+Web.swift
================================================
//
// ViewController+Web.swift
// FSNotes
//
// Created by Oleksandr Hlushchenko on 15.09.2022.
// Copyright © 2022 Oleksandr Hlushchenko. All rights reserved.
//
import Cocoa
import Shout
extension EditorViewController {
public func getCurrentNote() -> Note? {
return vcEditor?.note
}
@IBAction func removeWebNote(_ sender: NSMenuItem) {
if !UserDefaultsManagement.customWebServer, let note = getCurrentNote() {
ViewController.shared()?.deleteAPI(note: note, completion: {
DispatchQueue.main.async {
ViewController.shared()?.notesTableView.reloadRow(note: note)
}
})
return
}
guard let note = getCurrentNote(), let remotePath = note.uploadPath else { return }
DispatchQueue.global().async {
do {
guard let ssh = self.getSSHResource() else { return }
try ssh.execute("rm -r \(remotePath)")
note.uploadPath = nil
Storage.shared().saveUploadPaths()
DispatchQueue.main.async {
ViewController.shared()?.notesTableView.reloadRow(note: note)
}
} catch {
print(error, error.localizedDescription)
}
}
}
@IBAction func uploadWebNote(_ sender: NSMenuItem) {
if !UserDefaultsManagement.customWebServer, let note = getCurrentNote() {
ViewController.shared()?.createAPI(note: note, completion: { url in
DispatchQueue.main.async {
ViewController.shared()?.notesTableView.reloadRow(note: note)
guard let url = url else { return }
let pasteboard = NSPasteboard.general
pasteboard.declareTypes([NSPasteboard.PasteboardType.string], owner: nil)
pasteboard.setString(url.absoluteString, forType: NSPasteboard.PasteboardType.string)
NSWorkspace.shared.open(url)
}
})
return
}
guard let note = getCurrentNote() else { return }
let dst = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("Upload")
try? FileManager.default.removeItem(at: dst)
guard let localURL = MPreviewView.buildPage(for: note, at: dst, web: true),
let sftpPath = UserDefaultsManagement.sftpPath,
let web = UserDefaultsManagement.sftpWeb else { return }
let latinName = note.getLatinName()
let remoteDir = "\(sftpPath)\(latinName)/"
let resultUrl = web + latinName + "/"
NSPasteboard.general.clearContents()
NSPasteboard.general.setString(web + latinName + "/", forType: .string)
let images = note.content.getImagesAndFiles()
DispatchQueue.global().async {
do {
guard let ssh = self.getSSHResource() else { return }
try ssh.execute("mkdir -p \(remoteDir)")
let zipURL = localURL
.deletingLastPathComponent()
.appendingPathComponent(note.getLatinName())
.appendingPathExtension("zip")
let sftp = try ssh.openSftp()
// Upload index.html
let remoteIndex = remoteDir + "index.html"
_ = try ssh.execute("rm -r \(remoteIndex)")
try sftp.upload(localURL: localURL, remotePath: remoteIndex)
// Upload archive
try? sftp.upload(localURL: zipURL, remotePath: remoteDir + note.getLatinName() + ".zip")
// Upload images
var imageDirCreationDone = false
for image in images {
if image.path.startsWith(string: "http://") || image.path.startsWith(string: "https://") {
continue
}
if !imageDirCreationDone {
try ssh.execute("mkdir -p \(remoteDir)/i")
imageDirCreationDone = true
}
try? sftp.upload(localURL: image.url, remotePath: remoteDir + "i/" + image.url.lastPathComponent)
}
if #available(macOS 10.14, *) {
DispatchQueue.main.async {
ViewController.shared()?.sendNotification()
ViewController.shared()?.notesTableView.reloadRow(note: note)
NSWorkspace.shared.open(URL(string: resultUrl)!)
}
}
print("Upload was successfull for note: \(note.title)")
note.uploadPath = remoteDir
Storage.shared().saveUploadPaths()
} catch {
print(error, error.localizedDescription)
}
}
}
private func getSSHResource() -> SSH? {
let host = UserDefaultsManagement.sftpHost
let port = UserDefaultsManagement.sftpPort
let username = UserDefaultsManagement.sftpUsername
let password = UserDefaultsManagement.sftpPassword
let passphrase = UserDefaultsManagement.sftpPassphrase
var publicKeyURL: URL?
var privateKeyURL: URL?
if let accessData = UserDefaultsManagement.sftpAccessData,
let bookmarks = NSKeyedUnarchiver.unarchiveObject(with: accessData) as? [URL: Data] {
for bookmark in bookmarks {
if bookmark.key.path.hasSuffix(".pub") {
publicKeyURL = bookmark.key
} else {
privateKeyURL = bookmark.key
}
}
}
if password.count == 0, publicKeyURL == nil || publicKeyURL == nil {
uploadError(text: "Please set private and public keys")
return nil
}
do {
let ssh = try SSH(host: host, port: port)
if password.count > 0 {
try ssh.authenticate(username: username, password: password)
} else if let publicKeyURL = publicKeyURL, let privateKeyURL = privateKeyURL {
try ssh.authenticate(username: username, privateKey: privateKeyURL.path, publicKey: publicKeyURL.path, passphrase: passphrase)
}
return ssh
} catch {
print(error, error.localizedDescription)
return nil
}
}
public func uploadError(text: String) {
let alert = NSAlert()
alert.alertStyle = .critical
alert.informativeText = NSLocalizedString("Upload error", comment: "")
alert.messageText = text
alert.beginSheetModal(for: self.view.window!)
}
public func showAlert(message: String) {
DispatchQueue.main.async {
let alert = NSAlert()
alert.alertStyle = .critical
alert.informativeText = NSLocalizedString(message, comment: "")
alert.messageText = NSLocalizedString("Web publishing error", comment: "")
alert.beginSheetModal(for: self.view.window!) { (returnCode: NSApplication.ModalResponse) -> Void in }
}
}
}
================================================
FILE: FSNotes/ViewController.swift
================================================
//
// ViewController.swift
// FSNotes
//
// Created by Oleksandr Glushchenko on 7/20/17.
// Copyright © 2017 Oleksandr Glushchenko. All rights reserved.
//
import Cocoa
import MASShortcut
import Foundation
import Shout
import UserNotifications
import WebKit
class ViewController: EditorViewController,
NSSplitViewDelegate,
NSOutlineViewDelegate,
NSOutlineViewDataSource,
NSTextFieldDelegate,
UNUserNotificationCenterDelegate {
// MARK: - Properties
public var fsManager: FileSystemEventManager?
public var projectSettingsViewController: ProjectSettingsViewController?
private var isPreLoaded = false
let storage = Storage.shared()
private var sidebarTimer = Timer()
private var selectRowTimer = Timer()
private let searchQueue = OperationQueue()
private let counterQueue = OperationQueue()
public static var gitQueue = OperationQueue()
public static var gitQueueBusy: Bool = false
public static var gitQueueOperationDate: Date?
public var prevCommit: Commit?
/* Git */
private var updateViews = [Note]()
var tagsScannerQueue = [Note]()
@available(*, deprecated, message: "Remove after macOS 10.15 is no longer supported")
public var printerLegacy: PrinterLegacy?
override var representedObject: Any? {
didSet { } // Update the view, if already loaded.
}
// MARK: - IBOutlets
@IBOutlet weak var nonSelectedLabel: NSTextField!
@IBOutlet weak var splitView: EditorSplitView!
@IBOutlet var editor: EditTextView!
@IBOutlet weak var editAreaScroll: EditorScrollView!
@IBOutlet weak var search: SearchTextField!
@IBOutlet weak var notesTableView: NotesTableView!
@IBOutlet var noteMenu: NSMenu!
@IBOutlet weak var sidebarOutlineView: SidebarOutlineView!
@IBOutlet weak var sidebarSplitView: NSSplitView!
@IBOutlet weak var notesListCustomView: NSView!
@IBOutlet weak var outlineHeader: OutlineHeaderView!
@IBOutlet weak var showInSidebar: NSMenuItem!
@IBOutlet weak var searchTopConstraint: NSLayoutConstraint!
@IBOutlet weak var lockedFolder: NSTextField!
@IBOutlet weak var newNoteButton: NSButton!
@IBOutlet weak var titleLabel: TitleTextField! {
didSet {
let clickGesture = NSClickGestureRecognizer()
clickGesture.target = self
clickGesture.numberOfClicksRequired = 2
clickGesture.buttonMask = 0x1
clickGesture.action = #selector(switchTitleToEditMode)
titleLabel.addGestureRecognizer(clickGesture)
}
}
@IBOutlet weak var shareButton: NSButton!
@IBOutlet weak var sortByOutlet: NSMenuItem!
@IBOutlet weak var titleBarAdditionalView: NSVisualEffectView! {
didSet {
let layer = CALayer()
layer.frame = titleBarAdditionalView.bounds
layer.backgroundColor = .clear
titleBarAdditionalView.wantsLayer = true
titleBarAdditionalView.layer = layer
titleBarAdditionalView.alphaValue = 0
}
}
@IBOutlet weak var previewButton: NSButton! {
didSet {
previewButton.state = vcEditor?.isPreviewEnabled() == true ? .on : .off
}
}
@IBOutlet weak var titleBarView: TitleBarView! {
didSet {
titleBarView.onMouseExitedClosure = { [weak self] in
DispatchQueue.main.async {
NSAnimationContext.runAnimationGroup({ context in
context.duration = 0.35
self?.titleBarAdditionalView.alphaValue = 0
self?.titleLabel.backgroundColor = .clear
}, completionHandler: nil)
}
}
titleBarView.onMouseEnteredClosure = { [weak self] in
DispatchQueue.main.async {
guard self?.titleLabel.isEnabled == false || self?.titleLabel.isEditable == false else { return }
if let note = self?.editor.note {
if note.isEncryptedAndLocked() {
self?.lockUnlock.image = NSImage(named: NSImage.lockLockedTemplateName)
} else {
self?.lockUnlock.image = NSImage(named: NSImage.lockUnlockedTemplateName)
}
}
self?.lockUnlock.isHidden = (self?.editor.note == nil)
NSAnimationContext.runAnimationGroup({ context in
context.duration = 0.35
self?.titleBarAdditionalView.alphaValue = 1
}, completionHandler: nil)
}
}
}
}
@IBOutlet weak var lockUnlock: NSButton!
@IBOutlet weak var sidebarScrollView: NSScrollView!
@IBOutlet weak var notesScrollView: NSScrollView!
@IBOutlet weak var menuChangeCreationDate: NSMenuItem!
@IBOutlet weak var counter: NSTextField!
@IBOutlet weak var notesCounterViewHeight: NSLayoutConstraint!
@IBOutlet weak var notesCounter: NSTextField!
// MARK: - Overrides
override func viewDidLoad() {
if isPreLoaded {
return
}
isPreLoaded = true
if #available(macOS 12.0, *) {
let image = NSImage(systemSymbolName: "square.and.pencil", accessibilityDescription: nil)
var config = NSImage.SymbolConfiguration(textStyle: .body, scale: .large)
config = config.applying(.init(paletteColors: [.systemTeal, .systemGray]))
newNoteButton.image = image?.withSymbolConfiguration(config)
} else {
newNoteButton.image = NSImage(imageLiteralResourceName: "new_note_button").resize(to: CGSize(width: 20, height: 20))
}
configureShortcuts()
configureDelegates()
configureLayout()
configureEditor()
// Must before event manager starts
self.storage.checkWelcome()
fsManager = FileSystemEventManager(storage: storage, delegate: self)
fsManager?.start()
loadBookmarks(data: UserDefaultsManagement.sftpAccessData)
loadBookmarks(data: UserDefaultsManagement.gitPrivateKeyData)
loadMoveMenu()
loadSortBySetting()
checkSidebarConstraint()
#if CLOUD_RELATED_BLOCK
registerKeyValueObserver()
#endif
ViewController.gitQueue.maxConcurrentOperationCount = 1
notesTableView.doubleAction = #selector(self.doubleClickOnNotesTable)
DispatchQueue.global().async {
self.storage.loadInboxAndTrash()
DispatchQueue.main.async {
self.buildSearchQuery()
self.configureSidebar()
self.configureNoteList()
}
}
}
override func viewDidAppear() {
// Init window size
if UserDefaultsManagement.isFirstLaunch {
if let window = self.view.window {
let newSize = NSSize(width: 1200, height: window.frame.height)
window.setContentSize(newSize)
window.center()
}
self.sidebarSplitView.setPosition(200, ofDividerAt: 0)
self.splitView.setPosition(300, ofDividerAt: 0)
UserDefaultsManagement.sidebarTableWidth = 200
UserDefaultsManagement.notesTableWidth = 300
UserDefaultsManagement.isFirstLaunch = false
}
// Restore window position
if let x = UserDefaultsManagement.lastScreenX,
let y = UserDefaultsManagement.lastScreenY {
view.window?.setFrameOrigin(NSPoint(x: x, y: y))
UserDefaultsManagement.lastScreenX = nil
UserDefaultsManagement.lastScreenY = nil
}
if UserDefaultsManagement.fullScreen {
view.window?.toggleFullScreen(nil)
}
}
public func preLoadProjectsData() {
let projectsLoading = Date()
let results = self.storage.getProjectDiffs()
OperationQueue.main.addOperation {
self.sidebarOutlineView.removeRows(projects: results.0)
self.sidebarOutlineView.insertRows(projects: results.1)
self.notesTableView.doVisualChanges(results: (results.2, results.3, []))
}
print("0. Projects diff loading finished in \(projectsLoading.timeIntervalSinceNow * -1) seconds")
let diffLoading = Date()
for project in self.storage.getProjects() {
let changes = project.checkNotesCacheDiff()
self.notesTableView.doVisualChanges(results: changes)
}
// Reload added projects
self.fsManager?.restart()
self.storage.migrationAPIIds()
print("1. Notes diff loading finished in \(diffLoading.timeIntervalSinceNow * -1) seconds")
let tagsPoint = Date()
// Schedule git actions
self.scheduleSnapshots()
self.schedulePull()
// Loads tags
self.storage.loadNotesContent()
DispatchQueue.main.async {
if self.storage.isCrashedLastTime && !UserDefaultsManagement.showWelcome {
// Unsafe – resets selected note
self.restoreSidebar()
}
UserDefaultsManagement.showWelcome = false
// Safe – only tags loading
self.sidebarOutlineView.loadAllTags()
}
print("2. Tags loading finished in \(tagsPoint.timeIntervalSinceNow * -1) seconds")
let highlightCachePoint = Date()
for note in self.storage.noteList {
note.cache()
}
print("3. Notes attributes cache for \(self.storage.noteList.count) notes in \(highlightCachePoint.timeIntervalSinceNow * -1) seconds")
let gitCachePoint = Date()
self.cacheGitRepositories()
print("4. git history cached in \(gitCachePoint.timeIntervalSinceNow * -1) seconds")
}
// MARK: - Initial configuration
private func configureLayout() {
dropTitle()
editor.configure()
notesTableView.setDraggingSourceOperationMask(.every, forLocal: false)
if (UserDefaultsManagement.horizontalOrientation) {
self.splitView.isVertical = false
notesCounterViewHeight.constant = 0
notesCounter.isHidden = true
}
self.menuChangeCreationDate.title = NSLocalizedString("Change Creation Date", comment: "Menu")
self.shareButton.sendAction(on: .leftMouseDown)
self.setTableRowHeight()
self.sidebarOutlineView.sidebarItems = Sidebar().getList()
self.sidebarOutlineView.reloadData()
sidebarOutlineView.selectionHighlightStyle = .regular
sidebarOutlineView.backgroundColor = .windowBackgroundColor
self.sidebarSplitView.autosaveName = "SidebarSplitView"
self.splitView.autosaveName = "EditorSplitView"
// Always show notes list at launch
if (self.splitView.subviews[0].frame.width < 10) {
self.splitView.setPosition(300, ofDividerAt: 0)
}
notesScrollView.scrollerStyle = .overlay
sidebarScrollView.scrollerStyle = .overlay
if let cell = search.cell as? NSSearchFieldCell {
cell.searchButtonCell?.target = self
cell.searchButtonCell?.action = #selector(openRecentPopup(_:))
}
DistributedNotificationCenter.default().addObserver(self, selector: #selector(onWakeNote(note:)), name: Notification.Name("com.apple.screenIsUnlocked"), object: nil)
NSWorkspace.shared.notificationCenter.addObserver(
self, selector: #selector(onSleepNote(note:)),
name: NSWorkspace.willSleepNotification, object: nil)
NSWorkspace.shared.notificationCenter.addObserver(
self, selector: #selector(onUserSwitch(note:)),
name: NSWorkspace.sessionDidBecomeActiveNotification, object: nil)
DistributedNotificationCenter.default().addObserver(
self,
selector: #selector(onScreenLocked(note:)),
name: NSNotification.Name(rawValue: "com.apple.screenIsLocked"),
object: nil
)
DistributedNotificationCenter.default().addObserver(
self,
selector: #selector(onAccentColorChanged(note:)),
name: NSNotification.Name(rawValue: "AppleColorPreferencesChangedNotification"),
object: nil
)
DistributedNotificationCenter.default.addObserver(
self,
selector: #selector(onAccentColorChanged(note:)),
name: NSNotification.Name(rawValue: "AppleInterfaceThemeChangedNotification"),
object: nil
)
}
public func restoreSidebar() {
self.sidebarOutlineView.sidebarItems = Sidebar().getList()
self.sidebarOutlineView.reloadData()
self.storage.restoreProjectsExpandState()
for project in self.storage.getProjects() {
if project.isExpanded {
self.sidebarOutlineView.expandItem(project)
}
}
}
public func configureSidebar() {
if isVisibleSidebar() {
self.restoreSidebar()
if UserDefaultsManagement.lastSidebarItem != nil || UserDefaultsManagement.lastProjectURL != nil || Storage.shared().welcomeProject != nil {
if let welcome = Storage.shared().welcomeProject {
let item = self.sidebarOutlineView.row(forItem: welcome)
if item > -1 {
self.sidebarOutlineView.selectRowIndexes([item], byExtendingSelection: false)
}
} else if let lastSidebarItem = UserDefaultsManagement.lastSidebarItem {
let sidebarItem = self.sidebarOutlineView.sidebarItems?.first(where: { ($0 as? SidebarItem)?.type.rawValue == lastSidebarItem })
let item = self.sidebarOutlineView.row(forItem: sidebarItem)
if item > -1 {
self.sidebarOutlineView.selectRowIndexes([item], byExtendingSelection: false)
}
} else if let lastURL = UserDefaultsManagement.lastProjectURL, let project = self.storage.getProjectBy(url: lastURL) {
let item = self.sidebarOutlineView.row(forItem: project)
if item > -1 {
self.sidebarOutlineView.selectRowIndexes([item], byExtendingSelection: false)
}
}
}
}
}
private func configureNoteList() {
updateTable() {
DispatchQueue.main.async {
// Init first selected note for welcome
if let note = Storage.shared().welcomeNote {
note.previewState = true
self.notesTableView.select(note: note)
Storage.shared().welcomeNote = nil
}
self.restoreOpenedWindows()
self.importAndCreate()
DispatchQueue.global().async {
self.preLoadProjectsData()
}
}
}
}
private func configureEditor() {
self.editor?.linkTextAttributes = [
.foregroundColor: NSColor.init(named: "link")!
]
self.editor.usesFindBar = true
self.editor.isIncrementalSearchingEnabled = true
editor.initTextStorage()
editor.editorViewController = self
self.editor.viewDelegate = self
// configure editor view controller
vcEditor = editor
vcTitleLabel = titleLabel
vcEditorScrollView = editAreaScroll
vcNonSelectedLabel = nonSelectedLabel
super.initView()
}
private func configureShortcuts() {
MASShortcutMonitor.shared().register(UserDefaultsManagement.newNoteShortcut, withAction: {
self.makeNoteShortcut()
})
MASShortcutMonitor.shared().register(UserDefaultsManagement.searchNoteShortcut, withAction: {
self.searchShortcut()
})
MASShortcutMonitor.shared().register(UserDefaultsManagement.quickNoteShortcut, withAction: {
self.quickNote(self)
})
MASShortcutMonitor.shared().register(UserDefaultsManagement.activateShortcut, withAction: {
self.searchShortcut(activate: true)
})
NSEvent.addLocalMonitorForEvents(matching: NSEvent.EventTypeMask.flagsChanged) {
return $0
}
NSEvent.addLocalMonitorForEvents(matching: NSEvent.EventTypeMask.keyDown) {
if self.keyDown(with: $0) {
return $0
}
return nil
}
}
private func configureDelegates() {
self.search.vcDelegate = self
self.search.delegate = self.search
self.sidebarSplitView.delegate = self
self.sidebarOutlineView.viewDelegate = self
if #available(macOS 10.14, *) {
UNUserNotificationCenter.current().delegate = self
}
}
// MARK: - Actions
@IBAction public func openRecentPopup(_ sender: Any) {
search.searchesMenu = search.generateRecentMenu()
let general = search.searchesMenu!.item(at: 0)
search.searchesMenu!.popUp(positioning: general, at: NSPoint(x: 5, y: search.frame.height + 7), in: search)
}
@IBAction func searchAndCreate(_ sender: Any) {
AppDelegate.mainWindowController?.window?.makeKeyAndOrderFront(nil)
guard let vc = ViewController.shared() else { return }
if let view = NSApplication.shared.mainWindow?.firstResponder as? NSTextView, let textField = view.superview?.superview {
if textField.isKind(of: SearchTextField.self) {
if vc.search.searchesMenu != nil {
vc.search.searchesMenu = nil
} else {
vc.search.searchesMenu = vc.search.generateRecentMenu()
let general = vc.search.searchesMenu!.item(at: 0)
vc.search.searchesMenu!.popUp(positioning: general, at: NSPoint(x: 5, y: vc.search.frame.height + 7), in: vc.search)
return
}
}
}
let size = UserDefaultsManagement.horizontalOrientation
? vc.splitView.subviews[0].frame.height
: vc.splitView.subviews[0].frame.width
if size == 0 {
toggleNoteList(self)
}
vc.search.window?.makeFirstResponder(vc.search)
}
@IBAction func sortBy(_ sender: NSMenuItem) {
if let id = sender.identifier {
let key = String(id.rawValue.dropFirst(3))
guard let sortBy = SortBy(rawValue: key) else { return }
if sortBy.rawValue == UserDefaultsManagement.sort.rawValue {
UserDefaultsManagement.sortDirection = !UserDefaultsManagement.sortDirection
}
UserDefaultsManagement.sort = sortBy
if let submenu = sortByOutlet.submenu {
for item in submenu.items {
item.state = NSControl.StateValue.off
}
}
sender.state = NSControl.StateValue.on
ViewController.shared()?.buildSearchQuery()
ViewController.shared()?.updateTable()
}
}
// Ask project password before move to encrypted
public func moveReq(notes: [Note], project: Project, completion: @escaping (Bool) -> ()) {
for note in notes {
if note.isEncrypted() && project.isEncrypted {
let alert = NSAlert()
alert.alertStyle = .critical
alert.informativeText = NSLocalizedString("You cannot move an already encrypted note to an encrypted directory. You must first decrypt the note and repeat the steps.", comment: "")
alert.messageText = NSLocalizedString("Move error", comment: "")
alert.runModal()
return
}
}
// Encrypted and locked
if project.isEncrypted && project.isLocked() {
getMasterPassword() { password in
self.sidebarOutlineView.unlock(projects: [project], password: password)
if project.password != nil {
DispatchQueue.main.async {
self.move(notes: notes, project: project)
for note in notes {
note.encryptAndUnlock(password: password)
}
completion(true)
}
return
}
completion(false)
}
return
}
self.move(notes: notes, project: project)
// Encrypted and non locked
if project.isEncrypted, let password = project.password {
for note in notes {
note.encryptAndUnlock(password: password)
}
}
completion(true)
}
private func move(notes: [Note], project: Project) {
let selectedRow = notesTableView.selectedRowIndexes.min()
for note in notes {
if note.project == project {
continue
}
if note.isEncrypted() {
_ = note.lock()
}
let destination = project.url.appendingPathComponent(note.name, isDirectory: false)
note.moveImages(to: project)
_ = note.move(to: destination, project: project)
if !storage.searchQuery.isFit(note: note) {
notesTableView.removeRows(notes: [note])
if let i = selectedRow, i > -1 {
if notesTableView.countNotes() > i {
notesTableView.selectRow(i)
} else {
notesTableView.selectRow(notesTableView.countNotes() - 1)
}
}
}
note.invalidateCache()
}
editor.clear()
}
override func viewDidResize() {
guard let vc = ViewController.shared() else { return }
vc.checkSidebarConstraint()
super.viewDidResize()
}
func reloadSideBar() {
guard let outline = sidebarOutlineView else { return }
sidebarTimer.invalidate()
sidebarTimer = Timer.scheduledTimer(timeInterval: 1.2, target: outline, selector: #selector(outline.reloadSidebar), userInfo: nil, repeats: false)
}
func setTableRowHeight() {
notesTableView.rowHeight = CGFloat(21 + UserDefaultsManagement.cellSpacing)
notesTableView.reloadData()
}
public func keyDown(with event: NSEvent) -> Bool {
guard let mw = MainWindowController.shared() else { return false }
guard self.alert == nil else {
if event.keyCode == kVK_Escape, let unwrapped = alert {
mw.endSheet(unwrapped.window)
self.alert = nil
}
return true
}
if event.modifierFlags.contains(.shift)
&& event.modifierFlags.contains(.option)
&& event.keyCode == kVK_ANSI_N {
createFolder(NSMenuItem())
return false
}
// Return / Cmd + Return navigation
if event.keyCode == kVK_Return {
if let fr = NSApp.mainWindow?.firstResponder, self.alert == nil {
if event.modifierFlags.contains(.command) {
if fr.isKind(of: NotesTableView.self) {
NSApp.mainWindow?.makeFirstResponder(self.sidebarOutlineView)
if sidebarOutlineView.selectedRowIndexes.count == 0 {
sidebarOutlineView.selectRowIndexes([0], byExtendingSelection: false)
} else {
sidebarOutlineView.selectRowIndexes(sidebarOutlineView.selectedRowIndexes, byExtendingSelection: false)
}
return false
}
if fr.isKind(of: EditTextView.self) || fr.isKind(of: MPreviewView.self) {
NSApp.mainWindow?.makeFirstResponder(self.notesTableView)
return false
}
} else {
if fr.isKind(of: SidebarOutlineView.self) {
self.notesTableView.selectCurrent()
NSApp.mainWindow?.makeFirstResponder(self.notesTableView)
return false
}
if let note = editor.note, fr.isKind(of: NotesTableView.self) {
if note.container != .encryptedTextPack {
if vcEditor?.isPreviewEnabled() == true {
disablePreview()
}
NSApp.mainWindow?.makeFirstResponder(editor)
}
return false
}
}
}
return true
}
// Tab / Control + Tab
if event.keyCode == kVK_Tab {
if event.modifierFlags.contains(.control) {
self.notesTableView.window?.makeFirstResponder(self.notesTableView)
return true
}
if let fr = NSApp.mainWindow?.firstResponder, fr.isKind(of: NotesTableView.self) {
NSApp.mainWindow?.makeFirstResponder(self.notesTableView)
return false
}
}
if event.keyCode == kVK_Escape && event.modifierFlags.contains(.option) {
editor.forceSystemAutocomplete = true
(view.window?.firstResponder as? NSTextView)?.complete(nil)
return true
}
// Focus search bar on ESC
if (
(
event.keyCode == kVK_Escape
|| (
event.characters == "." &&
event.modifierFlags.contains(.command)
)
)
&& NSApplication.shared.mainWindow == NSApplication.shared.keyWindow
&& UserDefaultsManagement.shouldFocusSearchOnESCKeyDown
&& !editor.hasMarkedText()
) {
self.view.window?.orderFront(nil)
self.view.window?.makeKey()
search.searchesMenu = nil
if NSApplication.shared.mainWindow?.firstResponder === editor, editor.selectedRange().length > 0 {
editor.selectedRange = NSRange(location: editor.selectedRange().upperBound, length: 0)
return false
}
if let view = NSApplication.shared.mainWindow?.firstResponder as? NSTextView, let textField = view.superview?.superview, textField.isKind(of: NameTextField.self) {
NSApp.mainWindow?.makeFirstResponder( self.notesTableView)
return false
}
if let mView = self.editor.markdownView, mView.isFindPanelVisible {
mView.hideFindPanel()
NSApp.mainWindow?.makeFirstResponder(mView.webView)
return false
}
if self.editAreaScroll.isFindBarVisible {
cancelTextSearch()
NSApp.mainWindow?.makeFirstResponder(editor)
return false
}
// Renaming is in progress
if titleLabel.isEditable {
titleLabel.editModeOff()
titleLabel.window?.makeFirstResponder(notesTableView)
return false
}
UserDefaultsManagement.lastSidebarItem = nil
UserDefaultsManagement.lastProjectURL = nil
UserDefaultsManagement.lastSelectedURL = nil
notesTableView.scroll(.zero)
let hasSelectedNotes = notesTableView.selectedRow > -1
let hasSelectedBarItem = sidebarOutlineView.selectedRow > -1
if hasSelectedBarItem && hasSelectedNotes {
UserDataService.instance.isNotesTableEscape = true
notesTableView.deselectAll(nil)
NSApp.mainWindow?.makeFirstResponder(search)
return false
}
sidebarOutlineView.deselectAll(nil)
sidebarOutlineView.scrollRowToVisible(0)
cleanSearchAndEditArea()
return true
}
// Search cmd-f
if (event.characters?.unicodeScalars.first == "f" && event.modifierFlags.contains(.command) && !event.modifierFlags.contains(.control)) {
if self.notesTableView.getSelectedNote() != nil {
if search.stringValue.count > 0 {
let fullText = search.stringValue
let startIndex = fullText.startIndex
let range = search.selectedRange
let selectionStart = fullText.index(startIndex, offsetBy: range.location)
let textBefore = String(fullText[startIndex.. 0 else {
sender.stringValue = note.getTitleWithoutLabel()
return
}
sender.isEditable = false
let newUrl = note.getNewURL(name: value)
UserDataService.instance.focusOnImport = newUrl
if note.url.path == newUrl.path {
return
}
note.overwrite(url: newUrl)
do {
try FileManager.default.moveItem(at: url, to: newUrl)
print("File moved from \"\(url.deletingPathExtension().lastPathComponent)\" to \"\(newUrl.deletingPathExtension().lastPathComponent)\"")
} catch {
note.overwrite(url: url)
}
}
@IBAction func makeMenu(_ sender: Any) {
guard let vc = ViewController.shared() else { return }
if let type = vc.getSidebarType(), type == .Trash {
vc.sidebarOutlineView.deselectAllRows()
}
_ = vc.createNote()
}
@IBAction func renameMenu(_ sender: Any) {
guard let vc = ViewController.shared() else { return }
vc.titleLabel.restoreResponder = vc.view.window?.firstResponder
vc.switchTitleToEditMode()
}
@objc func switchTitleToEditMode() {
guard let vc = ViewController.shared() else { return }
if vc.notesTableView.selectedRow > -1 {
vc.titleLabel.editModeOn()
vc.titleBarAdditionalView.alphaValue = 0
if let note = vc.editor.note, note.getFileName().isValidUUID {
vc.titleLabel.stringValue = note.getFileName()
}
return
}
if let md = AppDelegate.mainWindowController {
if let actionOnDoubleClick = UserDefaults.standard.object(forKey: "AppleActionOnDoubleClick") as? String {
switch actionOnDoubleClick {
case "Maximize":
md.maximizeWindow()
case "Minimize":
md.window?.performMiniaturize(nil)
default:
break
}
}
}
}
@IBAction func toggleNoteList(_ sender: Any) {
guard let vc = ViewController.shared() else { return }
let size = UserDefaultsManagement.horizontalOrientation
? vc.splitView.subviews[0].frame.height
: vc.splitView.subviews[0].frame.width
if size == 0 {
var size = UserDefaultsManagement.notesTableWidth
if UserDefaultsManagement.notesTableWidth == 0 {
size = 300
}
vc.splitView.shouldHideDivider = false
vc.splitView.setPosition(size, ofDividerAt: 0)
} else if vc.splitView.shouldHideDivider {
vc.splitView.shouldHideDivider = false
vc.splitView.setPosition(UserDefaultsManagement.notesTableWidth, ofDividerAt: 0)
} else {
UserDefaultsManagement.notesTableWidth = size
vc.splitView.shouldHideDivider = true
vc.splitView.setPosition(0, ofDividerAt: 0)
DispatchQueue.main.async {
vc.splitView.setPosition(0, ofDividerAt: 0)
}
}
vc.editor.updateTextContainerInset()
}
@IBAction func toggleSidebar(_ sender: Any) {
guard let vc = ViewController.shared() else { return }
if isVisibleSidebar() {
UserDefaultsManagement.sidebarTableWidth = vc.sidebarSplitView.subviews[0].frame.width
vc.sidebarSplitView.setPosition(0, ofDividerAt: 0)
} else {
vc.sidebarSplitView.setPosition(UserDefaultsManagement.sidebarTableWidth, ofDividerAt: 0)
vc.reloadSideBar()
}
vc.editor.updateTextContainerInset()
}
@IBAction func emptyTrash(_ sender: NSMenuItem) {
let notes = storage.getAllTrash()
for note in notes {
_ = note.removeFile()
}
NSSound(named: "Pop")?.play()
}
@IBAction func lockAll(_ sender: Any) {
let projects = storage.getProjects().filter({ $0.isEncrypted && !$0.isLocked() })
sidebarOutlineView.lock(projects: projects)
let editors = AppDelegate.getEditTextViews()
var unlockedEditors = [EditTextView]()
for editor in editors {
if let note = editor.note, note.isUnlocked() {
unlockedEditors.append(editor)
}
}
for editor in unlockedEditors {
editor.lockEncryptedView()
}
let notes = storage.noteList.filter({ $0.isUnlocked() })
for note in notes {
if note.lock() {
removeTags(note: note)
notesTableView.reloadRow(note: note)
}
}
if let window = notesTableView.window, window == view.window {
window.makeFirstResponder(notesTableView)
}
}
@available(macOS 10.14, *)
public func sendNotification() {
let center = UNUserNotificationCenter.current()
center.delegate = self
center.requestAuthorization(options: [.badge,.sound,.alert]) { granted, error in
if error != nil {
print("User permission is not granted : \(granted)")
}
}
let content = UNMutableNotificationContent()
content.title = "Upload over SSH done"
content.sound = .default
let date = Date().addingTimeInterval(1)
let dateComponent = Calendar.current.dateComponents([.year,.month,.day,.hour,.minute,.second], from: date)
let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponent, repeats: false)
let uuid = UUID().uuidString
let request = UNNotificationRequest(identifier: uuid, content: content, trigger: trigger)
center.add(request) { error in }
}
func controlTextDidEndEditing(_ obj: Notification) {
guard let textField = obj.object as? NSTextField, textField == titleLabel else { return }
if titleLabel.isEditable == true {
titleLabel.editModeOff()
fileName(titleLabel)
view.window?.makeFirstResponder(notesTableView)
}
else {
if let currentNote = notesTableView.getSelectedNote() {
updateTitle(note: currentNote)
}
}
}
public func reSort(note: Note) {
if !updateViews.contains(note) {
updateViews.append(note)
}
rowUpdaterTimer.invalidate()
rowUpdaterTimer = Timer.scheduledTimer(timeInterval: 1.2, target: self, selector: #selector(updateTableViews), userInfo: nil, repeats: false)
}
public func removeForever() {
guard let vc = ViewController.shared() else { return }
guard let notes = vc.notesTableView.getSelectedNotes() else { return }
guard let window = MainWindowController.shared() else { return }
vc.alert = NSAlert()
guard let alert = vc.alert else { return }
alert.messageText = String(format: NSLocalizedString("Are you sure you want to irretrievably delete %d note(s)?", comment: ""), notes.count)
alert.informativeText = NSLocalizedString("This action cannot be undone.", comment: "")
alert.addButton(withTitle: NSLocalizedString("Remove note(s)", comment: ""))
alert.addButton(withTitle: NSLocalizedString("Cancel", comment: ""))
alert.beginSheetModal(for: window) { (returnCode: NSApplication.ModalResponse) -> Void in
if returnCode == NSApplication.ModalResponse.alertFirstButtonReturn {
let selectedRow = vc.notesTableView.selectedRowIndexes.min()
vc.editor.clear()
vc.storage.removeNotes(notes: notes, completely: true) { _ in
DispatchQueue.main.async {
vc.notesTableView.removeRows(notes: notes)
if let i = selectedRow, i > -1 {
vc.notesTableView.selectRow(i)
}
}
}
}
vc.alert = nil
}
}
@objc private func updateTableViews() {
let editors = AppDelegate.getEditTextViews()
notesTableView.beginUpdates()
for note in updateViews {
notesTableView.reloadRow(note: note)
if search.stringValue.count == 0 {
sortAndMove(note: note)
}
// Reloading nstextview in multiple windows
for editor in editors {
if let window = editor.window, let editorNote = editor.note, editorNote == note {
if editor.viewDelegate != nil { // Main window
self.updateCounters(note: editorNote)
}
if !editor.isLastEdited, !window.isKeyWindow {
editor.editorViewController?.refillEditArea(force: true)
}
}
}
}
updateViews.removeAll()
notesTableView.endUpdates()
}
public func updateCounters(note: Note? = nil, charRange: NSRange? = nil) {
guard let note = note else {
self.counter.stringValue = String()
return
}
counterQueue.cancelAllOperations()
let operation = BlockOperation()
operation.addExecutionBlock { [weak self] in
var title = String()
if let charRange = charRange, charRange.length > 0 {
if let string = note.content.string.substring(nsRange: charRange) {
title = "W: \(string.countWords()) | C: \(string.countChars())"
}
} else {
title = "W: \(note.content.string.countWords()) | C: \(note.content.string.countChars())"
}
if operation.isCancelled { return }
DispatchQueue.main.async {
self?.counter.stringValue = title
}
}
counterQueue.addOperation(operation)
}
public func updateNotesCounter() {
var i = 0
if notesTableView.selectedRowIndexes.count > 0 {
i = notesTableView.selectedRowIndexes.count
} else {
i = notesTableView.countNotes()
}
notesCounter.stringValue = "N: \(i)"
}
func getSidebarType() -> SidebarItemType? {
let sidebarItem = sidebarOutlineView.item(atRow: sidebarOutlineView.selectedRow) as? SidebarItem
if let type = sidebarItem?.type {
return type
}
return nil
}
public func getSidebarItem() -> SidebarItem? {
if let sidebarItem = sidebarOutlineView.item(atRow: sidebarOutlineView.selectedRow) as? SidebarItem {
return sidebarItem
}
return nil
}
func updateTable(completion: @escaping () -> Void = {}) {
let timestamp = Date().toMillis()
self.search.timestamp = timestamp
self.searchQueue.cancelAllOperations()
let operation = BlockOperation()
operation.addExecutionBlock { [weak self] in
guard let self = self else {return}
let projects = Storage.shared().searchQuery.projects
for project in projects {
self.preLoadNoteTitles(in: project)
}
let source = self.storage.noteList
var notes = [Note]()
for note in source {
if operation.isCancelled {
completion()
return
}
if self.storage.searchQuery.isFit(note: note) {
notes.append(note)
}
}
let orderedNotesList = self.storage.sortNotes(noteList: notes, operation: operation)
if orderedNotesList == self.notesTableView.getNoteList() {
// important for cleanSearchAndEditArea func call
completion()
return
}
if operation.isCancelled {
return
}
guard orderedNotesList.count > 0 else {
DispatchQueue.main.async {
self.editor.clear()
self.notesTableView.setNoteList(notes: orderedNotesList)
self.notesTableView.reloadData()
self.updateNotesCounter()
completion()
}
return
}
DispatchQueue.main.async {
self.notesTableView.setNoteList(notes: orderedNotesList)
self.notesTableView.reloadData()
self.updateNotesCounter()
completion()
}
}
self.searchQueue.addOperation(operation)
}
/*
Load titles in cases sort by Title
*/
private func preLoadNoteTitles(in project: Project) {
if (UserDefaultsManagement.sort == .title || project.settings.sortBy == .title) && project.settings.isFirstLineAsTitle() {
let notes = storage.noteList.filter({ $0.project == project })
for note in notes {
if !note.isLoaded {
note.load()
}
note.loadPreviewInfo()
}
}
}
public func reloadFonts() {
let webkitPreview = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("wkPreview")
try? FileManager.default.removeItem(at: webkitPreview)
Storage.shared().resetCacheAttributes()
let editors = AppDelegate.getEditTextViews()
for editor in editors {
if let evc = editor.editorViewController {
MPreviewView.template = nil
NotesTextProcessor.resetCaches()
evc.refillEditArea(force: true)
}
}
}
public func buildSearchQuery() {
let searchQuery = SearchQuery()
var projects = [Project]()
var tags = [String]()
var type: SidebarItemType?
if let sidebarProjects = sidebarOutlineView.getSidebarProjects() {
projects = sidebarProjects
}
// Iniot welcome project
if let project = Storage.shared().welcomeProject {
projects = [project]
}
if let sidebarTags = sidebarOutlineView.getSidebarTags() {
tags = sidebarTags
let currentModifiers = NSEvent.modifierFlags
let isCommandPressed = currentModifiers.contains(.command)
let isShiftPressed = currentModifiers.contains(.shift)
if isCommandPressed && isShiftPressed {
searchQuery.tagsModifierAnd(true)
}
}
if let sidebarTableView = self.sidebarOutlineView {
let indexPaths = sidebarTableView.selectedRowIndexes
for indexPath in indexPaths {
if let item = sidebarTableView.item(atRow: indexPath) as? SidebarItem {
if item.type == .All ||
item.type == .Untagged ||
item.type == .Todo ||
item.type == .Trash ||
item.type == .Inbox {
type = item.type
}
}
}
}
if projects.count == 0 && type == nil {
type = .All
}
let filter = search.stringValue
searchQuery.projects = projects
searchQuery.tags = tags
searchQuery.setFilter(filter)
if let type = type {
searchQuery.setType(type)
}
self.storage.setSearchQuery(value: searchQuery)
}
@objc func selectNullTableRow(note: Note) {
self.selectRowTimer.invalidate()
self.selectRowTimer = Timer.scheduledTimer(timeInterval: TimeInterval(0.2), target: self, selector: #selector(self.selectRowInstant), userInfo: note, repeats: false)
}
@objc private func selectRowInstant(_ timer: Timer) {
if let note = timer.userInfo as? Note {
if let i = self.notesTableView.getIndex(for: note) {
notesTableView.selectRowIndexes([i], byExtendingSelection: false)
notesTableView.scrollRowToVisible(i)
}
}
}
func focusTable() {
let index = self.notesTableView.selectedRow > -1 ? self.notesTableView.selectedRow : 0
self.notesTableView.window?.makeFirstResponder(self.notesTableView)
self.notesTableView.selectRowIndexes([index], byExtendingSelection: false)
self.notesTableView.scrollRowToVisible(index)
}
func cleanSearchAndEditArea(shouldBecomeFirstResponder: Bool = true, completion: (() -> ())? = nil) {
search.stringValue = ""
search.lastSearchQuery = ""
if shouldBecomeFirstResponder {
search.becomeFirstResponder()
}
notesTableView.selectRowIndexes(IndexSet(), byExtendingSelection: false)
editor.clear()
updateCounters(note: nil)
self.buildSearchQuery()
self.updateTable() {
DispatchQueue.main.async {
if shouldBecomeFirstResponder {
self.sidebarOutlineView.reloadTags()
}
if let completion = completion {
completion()
return
}
}
}
}
func makeNoteShortcut() {
let clipboard = NSPasteboard.general.string(forType: NSPasteboard.PasteboardType.string)
if let clipboard = clipboard {
_ = createNote(content: clipboard)
UNUserNotificationCenter.current().getNotificationSettings { settings in
guard settings.authorizationStatus == .notDetermined else { return }
UNUserNotificationCenter.current().requestAuthorization(
options: [.alert, .sound]
) { _, _ in }
}
let content = UNMutableNotificationContent()
content.title = NSLocalizedString("Clipboard successfully saved", comment: "")
content.body = clipboard
content.sound = .default
UNUserNotificationCenter.current().add(
UNNotificationRequest(
identifier: UUID().uuidString,
content: content,
trigger: nil
))
}
}
func searchShortcut(activate: Bool = false) {
guard let mainWindow = MainWindowController.shared() else { return }
if (
NSApplication.shared.isActive
&& !NSApplication.shared.isHidden
&& !mainWindow.isMiniaturized
) {
NSApplication.shared.hide(nil)
return
}
UserDefaultsManagement.lastScreenX = nil
UserDefaultsManagement.lastScreenY = nil
NSApp.activate(ignoringOtherApps: true)
mainWindow.makeKeyAndOrderFront(self)
guard let controller = mainWindow.contentViewController as? ViewController
else { return }
if !activate {
mainWindow.makeFirstResponder(controller.search)
}
}
public func sortAndMove(note: Note, project: Project? = nil) {
guard let srcIndex = notesTableView.getIndex(for: note) else { return }
let notes = notesTableView.getNoteList()
let resorted = storage.sortNotes(noteList: notes)
guard let dstIndex = resorted.firstIndex(of: note) else { return }
if srcIndex != dstIndex {
notesTableView.moveRow(at: srcIndex, to: dstIndex)
notesTableView.setNoteList(notes: resorted)
}
}
func pin(selectedNotes: [Note], toggle: Bool = false) {
if selectedNotes.count == 0 {
return
}
var state = notesTableView.getNoteList()
var updatedNotes = [(Int, Note)]()
for selectedNote in selectedNotes {
guard let atRow = notesTableView.getIndex(for: selectedNote),
let rowView = notesTableView.rowView(atRow: atRow, makeIfNecessary: false) as? NoteRowView,
let cell = rowView.view(atColumn: 0) as? NoteCellView else { continue }
updatedNotes.append((atRow, selectedNote))
if toggle {
selectedNote.togglePin()
}
cell.renderPin()
}
let resorted = storage.sortNotes(noteList: notesTableView.getNoteList())
notesTableView.beginUpdates()
let nowPinned = updatedNotes.filter { _, note in note.isPinned }
for (row, note) in nowPinned {
guard let newRow = resorted.firstIndex(where: { $0 === note }) else { continue }
notesTableView.moveRow(at: row, to: newRow)
let toMove = state.remove(at: row)
state.insert(toMove, at: newRow)
}
let nowUnpinned = updatedNotes
.filter({ (_, note) -> Bool in !note.isPinned })
.compactMap({ (_, note) -> (Int, Note)? in
guard let curRow = state.firstIndex(where: { $0 === note }) else { return nil }
return (curRow, note)
})
for (row, note) in nowUnpinned.reversed() {
guard let newRow = resorted.firstIndex(where: { $0 === note }) else { continue }
notesTableView.moveRow(at: row, to: newRow)
let toMove = state.remove(at: row)
state.insert(toMove, at: newRow)
}
notesTableView.setNoteList(notes: resorted)
notesTableView.endUpdates()
//notesTableView.reloadData()
//notesTableView.selectRowIndexes(newIndexes, byExtendingSelection: false)
}
func external(selectedNotes: [Note]) {
if selectedNotes.count == 0 {
return
}
for note in selectedNotes {
var path = note.url.path
if note.isTextBundle() && !note.isUnlocked(), let url = note.getContentFileURL() {
path = url.path
}
NSWorkspace.shared.openFile(path, withApplication: UserDefaultsManagement.externalEditor)
}
}
private func loadBookmarks(data: Data?) {
if let accessData = data,
let bookmarks = try? NSKeyedUnarchiver.unarchivedObject(ofClasses: [NSDictionary.self, NSURL.self, NSData.self], from: accessData) as? [URL: Data] {
for bookmark in bookmarks {
var isStale = false
do {
let url = try URL.init(resolvingBookmarkData: bookmark.value, options: NSURL.BookmarkResolutionOptions.withSecurityScope, relativeTo: nil, bookmarkDataIsStale: &isStale)
if !url.startAccessingSecurityScopedResource() {
print("RSA key not available: \(url.path)")
} else {
print("Access for RSA key is successfull restored \(url)")
}
} catch {
print("Error restoring sftp bookmark: \(error)")
}
}
}
}
func loadSortBySetting() {
let viewLabel = NSLocalizedString("View", comment: "Menu")
let sortByLabel = NSLocalizedString("Sort by", comment: "View menu")
guard
let menu = NSApp.menu,
let view = menu.item(withTitle: viewLabel),
let submenu = view.submenu,
let sortMenu = submenu.item(withTitle: sortByLabel),
let sortItems = sortMenu.submenu else {
return
}
let sort = UserDefaultsManagement.sort
for item in sortItems.items {
if let id = item.identifier, id.rawValue == "SB.\(sort.rawValue)" {
item.state = NSControl.StateValue.on
}
}
}
func registerKeyValueObserver() {
NotificationCenter.default.addObserver(self,
selector: #selector(ubiquitousKeyValueStoreDidChange(_:)),
name: NSUbiquitousKeyValueStore.didChangeExternallyNotification,
object: NSUbiquitousKeyValueStore.default)
if NSUbiquitousKeyValueStore.default.synchronize() == false {
fatalError("This app was not built with the proper entitlement requests.")
}
NSUbiquitousKeyValueStore.default.synchronize()
}
@objc func ubiquitousKeyValueStoreDidChange(_ notification: NSNotification) {
if let keys = notification.userInfo?[NSUbiquitousKeyValueStoreChangedKeysKey] as? [String] {
for key in keys {
if key == "co.fluder.fsnotes.pins.shared" {
let result = storage.restoreCloudPins()
DispatchQueue.main.async {
if let added = result.added {
ViewController.shared()?.pin(selectedNotes: added)
}
if let removed = result.removed {
ViewController.shared()?.pin(selectedNotes: removed)
}
}
}
if key.startsWith(string: "es.fsnot.project-settings") {
let settingsKey = key.replacingOccurrences(of: "es.fsnot.project-settings", with: "")
if let project = storage.getProjectBy(settingsKey: settingsKey) {
project.reloadSettings()
DispatchQueue.main.async {
if let result = project.loadWebAPI() {
let toReload = result.0 + result.1
for note in toReload {
ViewController.shared()?.notesTableView.reloadRow(note: note)
}
}
}
}
}
}
}
}
func checkSidebarConstraint() {
if sidebarSplitView.subviews[0].frame.width > 50 {
searchTopConstraint.constant = 8
return
}
if UserDefaultsManagement.hideSidebarTable || sidebarSplitView.subviews[0].frame.width < 50 {
searchTopConstraint.constant = CGFloat(25)
return
}
searchTopConstraint.constant = 8
}
@IBAction func sidebarItemVisibility(_ sender: NSMenuItem) {
sender.state = sender.state == .on ? .off : .on
let isChecked = sender.state == .on
switch sender.tag {
case 1:
UserDefaultsManagement.sidebarVisibilityInbox = isChecked
case 2:
UserDefaultsManagement.sidebarVisibilityNotes = isChecked
case 3:
UserDefaultsManagement.sidebarVisibilityTodo = isChecked
case 5:
UserDefaultsManagement.sidebarVisibilityTrash = isChecked
case 6:
UserDefaultsManagement.sidebarVisibilityUntagged = isChecked
default:
break
}
ViewController.shared()?.sidebarOutlineView.reloadSidebar()
}
@IBAction func prevHistory(_ sender: NSMenuItem) {
guard let vc = ViewController.shared() else { return }
if vc.notesTableView.historyPosition > 0 {
let prev = vc.notesTableView.historyPosition - 1
let prevUrl = vc.notesTableView.history[prev]
if let note = Storage.shared().getBy(url: prevUrl) {
vc.notesTableView.saveNavigationHistory(note: note)
vc.cleanSearchAndEditArea(completion: { () -> Void in
vc.notesTableView.selectRowAndSidebarItem(note: note)
})
}
vc.notesTableView.historyPosition = prev
}
}
@IBAction func nextHistory(_ sender: NSMenuItem) {
guard let vc = ViewController.shared() else { return }
if vc.notesTableView.historyPosition < vc.notesTableView.history.count - 1 {
let next = vc.notesTableView.historyPosition + 1
let nextUrl = vc.notesTableView.history[next]
if let note = Storage.shared().getBy(url: nextUrl) {
vc.cleanSearchAndEditArea(completion: { () -> Void in
vc.notesTableView.selectRowAndSidebarItem(note: note)
})
}
vc.notesTableView.historyPosition = next
}
}
func textView(_ view: NSTextView, menu: NSMenu, for event: NSEvent, at charIndex: Int) -> NSMenu? {
for item in menu.items {
if item.title == NSLocalizedString("Copy Link", comment: "") {
item.action = #selector(NSText.copy(_:))
}
if item.title == NSLocalizedString("Font", comment: "")
|| item.title == "Make Link"
|| item.title == NSLocalizedString("Make Link", comment: "") {
menu.removeItem(item)
}
}
return menu
}
func splitViewWillResizeSubviews(_ notification: Notification) {
editor.updateTextContainerInset()
}
public static func shared() -> ViewController? {
return AppDelegate.mainWindowController?.window?.contentViewController as? ViewController
}
public func copy(project: Project, url: URL) -> URL {
let fileName = url.lastPathComponent
let destination = project.url.appendingPathComponent(fileName)
do {
try FileManager.default.copyItem(at: url, to: destination)
return destination
} catch {
let dst = NameHelper.generateCopy(file: url, dstDir: project.url)
try? FileManager.default.copyItem(at: url, to: dst)
return dst
}
}
@objc func onSleepNote(note: NSNotification) {
if UserDefaultsManagement.lockOnSleep {
lockAll(self)
}
}
@objc func onScreenLocked(note: NSNotification) {
if UserDefaultsManagement.lockOnScreenActivated{
lockAll(self)
}
}
@objc func onAccentColorChanged(note: NSNotification) {
sidebarOutlineView.reloadSidebar()
}
@objc func onUserSwitch(note: NSNotification) {
if UserDefaultsManagement.lockOnUserSwitch {
lockAll(self)
}
}
override func restoreUserActivityState(_ userActivity: NSUserActivity) {
guard let name = userActivity.userInfo?["note-file-name"] as? String,
let state = userActivity.userInfo?["state"] as? String,
let note = Storage.shared().getBy(name: name)
else { return }
vcEditor?.changePreviewState(state == "preview")
note.previewState = state == "preview"
notesTableView.selectRowAndSidebarItem(note: note)
}
/*
Needs update UserActivity if selection did change
*/
func textViewDidChangeSelection(_ notification: Notification) {
guard let textView = notification.object as? NSTextView else { return }
if textView.window?.firstResponder == textView {
let range = editor.selectedRange()
if let editor = self.editor, let note = editor.note {
self.updateCounters(note: note, charRange: range)
}
// Save position
editor.note?.setSelectedRange(range: textView.selectedRange())
}
editor.userActivity?.needsSave = true
}
@objc func doubleClickOnNotesTable() {
let selected = notesTableView.clickedRow
if (selected < 0) {
return
}
if let note = notesTableView.getNote(at: selected) {
openInNewWindow(note: note)
}
}
public func restoreOpenedWindows() {
guard let documentDir = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first else { return }
let projectsDataUrl = documentDir.appendingPathComponent("editors.settings")
guard let data = try? Data(contentsOf: projectsDataUrl) else { return }
guard let unarchivedData = try? NSKeyedUnarchiver.unarchivedObject(ofClasses: [NSArray.self, NSDictionary.self, NSString.self, NSData.self, NSNumber.self, NSURL.self], from: data) as? [[String: Any]] else { return }
var mainKey = false
for item in unarchivedData.reversed() {
guard let url = item["url"] as? URL,
let frameData = item["frame"] as? Data,
let main = item["main"] as? Bool,
let isKeyWindow = item["key"] as? Bool,
let preview = item["preview"] as? Bool,
let note = self.storage.getBy(url: url)
else { continue }
if main {
if isKeyWindow {
mainKey = true
}
editor.changePreviewState(preview)
if let i = self.notesTableView.getIndex(for: note) {
note.previewState = self.editor.isPreviewEnabled()
self.notesTableView.saveNavigationHistory(note: note)
self.notesTableView.selectRow(i)
self.notesTableView.scrollRowToVisible(i)
self.editor.window?.makeFirstResponder(self.editor)
}
} else {
guard let frame = try? NSKeyedUnarchiver.unarchivedObject(ofClass: NSValue.self, from: frameData)?.rectValue else { continue }
self.openInNewWindow(note: note, frame: frame, preview: preview)
}
}
if mainKey {
NSApp.activate(ignoringOtherApps: true)
self.view.window?.makeKeyAndOrderFront(self)
}
}
// Important call after initial updateTable
public func importAndCreate() {
if let appDelegate = NSApplication.shared.delegate as? AppDelegate {
// fsnotes://find
if let url = appDelegate.url {
appDelegate.url = nil
appDelegate.search(url: url)
return
}
// Open files in the app
if let urls = appDelegate.urls {
appDelegate.importNotes(urls: urls)
return
}
// fsnotes://new/?title=URI-title&txt=URI-content
let name = appDelegate.newName
let content = appDelegate.newContent
if nil != name || nil != content {
if let note = self.createNote(name: name ?? "", content: content ?? "", openInNewWindow: appDelegate.newWindow), appDelegate.newWindow {
openInNewWindow(note: note)
}
}
}
}
public func isVisibleNoteList() -> Bool {
guard let vc = ViewController.shared() else { return false }
let size = UserDefaultsManagement.horizontalOrientation
? vc.splitView.subviews[0].frame.height
: vc.splitView.subviews[0].frame.width
if size == 0 || vc.splitView.shouldHideDivider {
return false
}
return true
}
public func isVisibleSidebar() -> Bool {
guard let vc = ViewController.shared() else { return false }
let size = Int(vc.sidebarSplitView.subviews[0].frame.width)
return size != 0
}
private func cacheGitRepositories() {
_ = Storage.shared().getProjects().filter({ $0.hasRepository() }).map({
$0.cacheHistory()
})
}
}
================================================
FILE: FSNotes/modern.icon/icon.json
================================================
{
"fill" : "automatic",
"groups" : [
{
"layers" : [
{
"fill-specializations" : [
{
"value" : {
"automatic-gradient" : "srgb:0.11674,0.11137,0.12082,1.00000"
}
},
{
"appearance" : "dark",
"value" : {
"automatic-gradient" : "srgb:0.85953,0.87116,0.86212,1.00000"
}
}
],
"image-name" : "Untitled-5.svg",
"name" : "row1",
"position" : {
"scale" : 1,
"translation-in-points" : [
-76.92312500000003,
-199.8671875
]
}
},
{
"fill-specializations" : [
{
"value" : {
"automatic-gradient" : "srgb:0.11674,0.11137,0.12082,1.00000"
}
},
{
"appearance" : "dark",
"value" : {
"automatic-gradient" : "srgb:0.85953,0.87116,0.86212,1.00000"
}
}
],
"image-name" : "Untitled-2 3.svg",
"name" : "row2",
"position" : {
"scale" : 1,
"translation-in-points" : [
-136.953125,
-51.15625
]
}
},
{
"fill-specializations" : [
{
"value" : {
"automatic-gradient" : "srgb:0.11674,0.11137,0.12082,1.00000"
}
},
{
"appearance" : "dark",
"value" : {
"automatic-gradient" : "srgb:0.85953,0.87116,0.86212,1.00000"
}
}
],
"image-name" : "Untitled-3 2.svg",
"name" : "row3",
"position" : {
"scale" : 1,
"translation-in-points" : [
-199.593125,
98.390625
]
}
},
{
"fill" : {
"solid" : "display-p3:0.02353,0.56863,1.00000,1.00000"
},
"image-name" : "Untitled-3 2.svg",
"name" : "row4",
"position" : {
"scale" : 1,
"translation-in-points" : [
200.44268750000003,
-51.15625
]
}
},
{
"fill" : {
"solid" : "display-p3:0.02353,0.56863,1.00000,1.00000"
},
"image-name" : "Untitled-2 3.svg",
"name" : "row5",
"position" : {
"scale" : 1,
"translation-in-points" : [
137.8046875,
98.390625
]
}
},
{
"fill" : {
"solid" : "display-p3:0.02353,0.56863,1.00000,1.00000"
},
"glass" : true,
"image-name" : "Untitled-3 2.svg",
"name" : "row6",
"position" : {
"scale" : 1,
"translation-in-points" : [
75.16468750000001,
247.140625
]
}
}
],
"shadow" : {
"kind" : "neutral",
"opacity" : 0.5
},
"translucency" : {
"enabled" : true,
"value" : 0.5
}
}
],
"supported-platforms" : {
"circles" : [
"watchOS"
],
"squares" : "shared"
}
}
================================================
FILE: FSNotes/mul.lproj/Main.xcstrings
================================================
{
"sourceLanguage" : "en",
"strings" : {
"0f7-Za-V0B.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Copyright © 2017-2024 Oleksandr Hlushchenko.\\nAll rights reserved.\"; ObjectID = \"0f7-Za-V0B\"; Note = \"#bc-ignore!\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copyright © 2017-2024 Oleksandr Hlushchenko.\nAll rights reserved."
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copyright © 2017-2024 Oleksandr Hlushchenko.\nVšechna práva vyhrazena."
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copyright © 2017-2024 Oleksandr Hlushchenko.\nAll rights reserved."
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Copyright © 2017-2024 Oleksandr Hlushchenko.\nAll rights reserved."
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copyright © 2017-2024 Oleksandr Hlushchenko.\nAll rights reserved."
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copyright © 2017-2024 Oleksandr Hlushchenko.\nAll rights reserved."
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copyright © 2017-2024 Oleksandr Hlushchenko.\nAll rights reserved."
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कॉपीराइट © 2017-2024 ऑलेक्ज़ेंडर ह्लुशेंको।\nसभी अधिकार सुरक्षित।"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copyright © 2017-2024 Oleksandr Hlushchenko.\nAll rights reserved."
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copyright © 2017-2024 Oleksandr Hlushchenko.\nAll rights reserved."
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copyright © 2017-2024 Oleksandr Hlushchenko.\nAll rights reserved."
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copyright © 2017-2024 Oleksandr Hlushchenko.\nAll rights reserved."
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copyright © 2017-2024 Oleksandr Hlushchenko.\nAll rights reserved."
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copyright © 2017-2024 Oleksandr Hlushchenko.\nAll rights reserved."
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copyright © 2017-2023 Oleksandr Hlushchenko.\nВсе права защищены."
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Telif hakkı © 2017-2024 Oleksandr Hlushchenko.\nHer hakkı saklıdır."
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copyright © 2017-2024 Oleksandr Hlushchenko.\nAll rights reserved."
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copyright © 2017-2024 Oleksandr Hlushchenko.\nAll rights reserved."
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copyright © 2017-2024 Oleksandr Hlushchenko.\nAll rights reserved."
}
}
}
},
"0o7-iB-dtg.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Activate:\"; ObjectID = \"0o7-iB-dtg\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aktivieren:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Activate:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Activar:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Activer :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "सक्रिय करें:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Attiva:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Активировать:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Etkinleştir:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Активувати:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "激活:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "啟用:"
}
}
}
},
"0Qp-Is-dNs.placeholderString" : {
"comment" : "Class = \"NSTextFieldCell\"; placeholderString = \"example.com\"; ObjectID = \"0Qp-Is-dNs\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "example.com"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "priklad.com"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "example.com"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "example.com"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "example.com"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "example.com"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "example.com"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "example.com"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "example.com"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "example.com"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "example.com"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "example.com"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "example.com"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "example.com"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "example.com"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "domainadi.com"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "example.com"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "example.com"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "example.com"
}
}
}
},
"1b7-l0-nxx.title" : {
"comment" : "Class = \"NSMenu\"; title = \"Find\"; ObjectID = \"1b7-l0-nxx\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "ابحث"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hledat"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Suchen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Find"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Buscar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rechercher"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "חפש"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "खोजे"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Trova"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "検索"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "찾기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zoeken"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pesquisar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pesquisar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Найти"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ara"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Знайти"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "查找"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "尋找"
}
}
}
},
"1cO-zi-naR.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"BackLinks\"; ObjectID = \"1cO-zi-naR\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Backlinks"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "BackLinks"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Enlaces externos"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Liens retour"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "बैकलिंक"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "BackLinks"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Обратные ссылки"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "BackLinks"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Зворотні посилання"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "反向链接"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "反向連結"
}
}
}
},
"1HB-X5-pmA.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"2 Spaces\"; ObjectID = \"1HB-X5-pmA\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "2 Spaces"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "2 mezery"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "2 Spaces"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "2 Spaces"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "2 Spaces"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "2 Spaces"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "2 Spaces"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "2 स्थान"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "2 Spaces"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "2 スペース"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "2 Spaces"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "2 Spaces"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "2 Spaces"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "2 Spaces"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "2 пробела"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "2 Boşluk"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "2 пробіли"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "缩进 2 个空格"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "2 個空格"
}
}
}
},
"1Kl-ap-nkv.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Locked\"; ObjectID = \"1Kl-ap-nkv\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Locked"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zamčeno"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Abgeschlossen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Locked"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloqueado"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verrouillé"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Locked"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "लॉक की गई"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloccato"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ロック"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "잠김"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Gesloten"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloqueado"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloqueado"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заблокировано"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kilitli"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Замкнено"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "锁定"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "已鎖定"
}
}
}
},
"1qV-pJ-ZQT.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Title\"; ObjectID = \"1qV-pJ-ZQT\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "عنوان"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nadpis"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Title"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Title"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Título"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Titre"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "כותרת"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "शीर्षक"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Titolo"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "タイトル"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "제목"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Titel"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Título"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Título"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заголовок"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Başlık"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заголовок"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "标题"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "標題"
}
}
}
},
"1sM-9Q-KeG.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"List\"; ObjectID = \"1sM-9Q-KeG\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "قائمة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Seznam"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Liste"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "List"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lista"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Liste"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "רשימה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "सूची"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lista"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "リスト"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "명부"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "List"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lista"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lista"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Список"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Liste"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Список"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "列表"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "清單"
}
}
}
},
"1Uk-jy-0qP.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Remove\"; ObjectID = \"1Uk-jy-0qP\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remove"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Odebrat"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remove"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Remove"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remove"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remove"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remove"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "हटाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remove"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remove"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remove"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remove"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remover"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remove"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Удалить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kaldır"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remove"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remove"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "移除"
}
}
}
},
"1Xt-HY-uBw.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"FSNotes\"; ObjectID = \"1Xt-HY-uBw\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "FSNotes"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
}
}
},
"1XY-bI-DX7.placeholderString" : {
"comment" : "Class = \"NSTextFieldCell\"; placeholderString = \"TextEdit\"; ObjectID = \"1XY-bI-DX7\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "TextEdit"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "TextEdit"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "TextEdit"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "TextEdit"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "TextEdit"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "TextEdit"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "TextEdit"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "TextEdit"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "TextEdit"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "TextEdit"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "텍스트 편집기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "TekstBewerken"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "TextEdit"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "TextEdit"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "TextEdit"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Metin Düzenle"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Текстовий редактор"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "TextEdit"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "文字編輯"
}
}
}
},
"2CI-mu-aiB.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Dock Icon:\"; ObjectID = \"2CI-mu-aiB\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "رمز الإرساء:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ikona:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dock icon:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Dock Icon:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Icono del Dock:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Icône de Dock :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "צלמית Dock:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "डॉक आइकन:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Icona Dock:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dock アイコン:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dock 아이콘:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dock icoon:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ícone da dock:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ícone da dock:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Иконка в Dock:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dock Simgesi"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Док іконка:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dock栏图标:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dock 圖示:"
}
}
}
},
"2Ci-Yj-aWK.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"New\"; ObjectID = \"2Ci-Yj-aWK\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "جديد"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nový"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Neu"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "New"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nuevo"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nouveau"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "חדש"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नया"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nuovo"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "新規"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "새로운 노트"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nieuw"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Novo"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Novo"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Новый"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yeni"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Нова нотатка"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "新建"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "新增"
}
}
}
},
"2Iq-vN-V2w.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"hour at\"; ObjectID = \"2Iq-vN-V2w\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "ساعة في"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "hodin, vždy"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "stunde um"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "hour at"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "hora a las"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "heure à"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "שעות ו-"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "घंटे पर"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "ore e"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "時間間隔 / 開始タイミング: "
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "시간 마다"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "uur bij"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "horas em"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "horas e"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "час в"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "saatte"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "годину"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "小时"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "時間於"
}
}
}
},
"2oI-Rn-ZJC.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Transformations\"; ObjectID = \"2oI-Rn-ZJC\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "التحولات"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Transformace"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Transformationen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Transformations"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Transformaciones"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Transformations"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "המרות"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "परिवर्तने"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Trasformazioni"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "変換"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "변형"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Transformaties"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Transformações"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Transformações"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Преобразования"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dönüşümler"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Трансформація"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "转换"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "轉換"
}
}
}
},
"2un-du-hJz.title" : {
"comment" : "Class = \"NSViewController\"; title = \"Git\"; ObjectID = \"2un-du-hJz\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Git"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "गिट"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
}
}
},
"2Vh-rt-1kc.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"New Note in New Window \"; ObjectID = \"2Vh-rt-1kc\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "ملاحظة جديدة في نافذة جديدة"
}
},
"cs" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Nové okno"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Neu In neuem Fenster"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "New Note in New Window "
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nueva nota en ventana nueva"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nouveau dans une nouvelle fenêtre"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הערה חדשה בחלון חדש"
}
},
"hi" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "नई विंडो"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nuova nota in una nuova finestra"
}
},
"ja" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "新しいウィンドウで新しいメモ"
}
},
"ko" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "새 창에서 새 메모"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Nieuwe notitie in nieuw venster"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Nova janela"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Nova nota em nova janela"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Новое заметка в новом окно"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yeni Pencere"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Нова нотатка у новому вікні"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "新窗口中的新笔记"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "在新視窗新增筆記"
}
}
}
},
"3fK-Ap-A5p.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Move Item\"; ObjectID = \"3fK-Ap-A5p\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Element verschieben"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Move Item"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mover elemento"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Déplacer l'élément"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "आइटम हटाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sposta elemento"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Переместить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Öğeyi Taşı"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перемістити елемент"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "移动项目"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "移動項目"
}
}
}
},
"3IN-sU-3Bg.title" : {
"comment" : "Class = \"NSMenu\"; title = \"Spelling and Grammar\"; ObjectID = \"3IN-sU-3Bg\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "التهجئة والقواعد اللغوية"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pravopis a gramatika"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rechtschreibung und Grammatik"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Spelling and Grammar"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ortografía y gramática"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Orthographe et grammaire"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "איות ודקדוק"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "वर्तनी और व्याकरण"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ortografia e Grammatica"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "スペルと文法"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "맞춤법 및 문법"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Spelling en grammatica"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ortografia e Gramática"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ortografia e Gramática"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Орфография и грамматика"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yazım ve Dilbilgisi"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Орфографія і граматика"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "拼写和语法"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "拼字與文法"
}
}
}
},
"3kn-9C-fsB.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Copy Title\"; ObjectID = \"3kn-9C-fsB\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "نسخ العنوان"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kopírovat nadpis"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Title kopieren"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Copy Title"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copiar título"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copier le titre"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "העתק כותרת"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "शीर्षक कॉपी करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copia titolo"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "タイトルをコピー"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "제목 복사"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kopieer titel"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copiar título"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copiar título"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Скопировать заголовок"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Başlığı Kopyala"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Скопіювати заголовок"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "拷贝标题"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "複製標題"
}
}
}
},
"3RO-C7-NOO.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Change Master Password\"; ObjectID = \"3RO-C7-NOO\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تغيير كلمة السر الرئيسية"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Změnit hlavní heslo"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Master Password ändern"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Change Master Password"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cambiar contraseña maestra"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Changer le mot de passe"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "שנה סיסמה ראשית"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "मास्टर पासवर्ड बदलें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cambia la Master Password"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "マスターパスワードを変更…"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "마스터 암호 변경"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verander Hoofdwachtwoord"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mudar senha mestra"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Palavra-passe Mestra"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Изменение мастер-пароля"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ana Parolayı Değiştir"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Змінити головний пароль"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "更改管理员密码"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "變更主密碼"
}
}
}
},
"3rS-ZA-NoH.title" : {
"comment" : "Class = \"NSMenu\"; title = \"Speech\"; ObjectID = \"3rS-ZA-NoH\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "كلام"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Řeč"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sprachausgabe"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Speech"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Habla"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Langage"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הקראה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "भाषण"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Voce"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "スピーチ"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "말하기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Spraak"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fala"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fala"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Диктовка"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Konuşma"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Промова"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "语音"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "語音"
}
}
}
},
"3rt-IC-kru.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"None Selected\"; ObjectID = \"3rt-IC-kru\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "None Selected "
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nic nevybráno"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Keine ausgewählt"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "None Selected"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ninguno Seleccionado"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "None Selected "
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "None Selected "
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कोई भी नहीं चुना गया"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nessuno selezionato"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "選択なし"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "선택되지 않음"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Geen geselecteerd"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nada selecionado"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nenhum selecionado"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Нет выбранных"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hiçbiri Seçilmedi"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Не вибрано"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "无选择"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "未選取"
}
}
}
},
"3tV-h0-YEb.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Open External\"; ObjectID = \"3tV-h0-YEb\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "فتح"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Otevřít externí"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Öffnen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Open External"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Abrir"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ouvrir"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "פתח"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "बाहरी खोलें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Apri"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "開く…"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "열기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Open"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Abrir External"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Abrir"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Открыть во внешнем"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Açık Harici"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Відкрити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "打开"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "在外部開啟"
}
}
}
},
"3zv-SD-lSX.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Create Folder\"; ObjectID = \"3zv-SD-lSX\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "مجلد جديد"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vytvořit složku"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Neuer Ordner"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Create Folder"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nueva carpeta"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nouveau dossier"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "תיקיה חדשה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "फोल्डर बनाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nuova cartella"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "新規フォルダ"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "새로운 폴더"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nieuwe map"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Criar pasta"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nova pasta"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Создать директорию"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Klasör Oluştur"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Нова директорія"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "新建文件夹"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "新增資料夾"
}
}
}
},
"4cz-zj-dkH.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Sort By:\"; ObjectID = \"4cz-zj-dkH\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "ترتيب حسب:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Řadit podle:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sortieren nach:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Sort By:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordenar por:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Trier par :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "מייו לפי:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "इसके अनुसार क्रमबद्ध करें:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordina per:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "表示順序:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "다음으로 정렬"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sorteer op:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordenar por:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordenar por:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сортировать по:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Göre sırala:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сортувати за:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "排序方式:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "排序方式:"
}
}
}
},
"4EN-yA-p0u.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Find\"; ObjectID = \"4EN-yA-p0u\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "بحث"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hledat"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Suchen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Find"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Buscar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rechercher"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "חפש"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "खोजे"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Trova"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "検索"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "찾기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zoeken"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pesquisar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pesquisar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Искать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ara"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Знайти"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "查找"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "尋找"
}
}
}
},
"4gs-Bc-GHG.placeholderString" : {
"comment" : "Class = \"NSTextFieldCell\"; placeholderString = \"hlushchenko\"; ObjectID = \"4gs-Bc-GHG\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "hlushchenko"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "hlushchenko"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "hlushchenko"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "hlushchenko"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "hlushchenko"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "hlushchenko"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "hlushchenko"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "ह्लुशेंको"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "hlushchenko"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "hlushchenko"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "hlushchenko"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "hlushchenko"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "hlushchenko"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "hlushchenko"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "hlushchenko"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "hlushchenko"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "hlushchenko"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "hlushchenko"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "hlushchenko"
}
}
}
},
"4J7-dP-txa.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Enter Full Screen\"; ObjectID = \"4J7-dP-txa\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "الدخول بشاشة كاملة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Spustit režim celé obrazovky"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vollbildmodus aktivieren"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Enter Full Screen"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Usar pantalla completa"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Entrer en mode plein écran"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "עבור למסך מלא"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पूर्ण स्क्रीन दर्ज करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Accedi a Schermo intero"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "フルスクリーンにする"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "전체 화면 시작"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Schakel schermvullende weergave in"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Entrar no modo de tela cheia"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Entrar em modo de ecrã completo"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вход в полноэкранный режим"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tam Ekrana Yap"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Повноекранний режим"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "进入全屏幕"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "進入全螢幕"
}
}
}
},
"4sb-4s-VLi.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Quit FSNotes\"; ObjectID = \"4sb-4s-VLi\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "الخروج من FSNotes"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ukončit FSNotes"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes beenden"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Quit FSNotes"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Salir de FSNotes"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Quitter FSNotes"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "סיים FSNotes"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes बंद करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Esci da FSNotes"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotesを終了"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes 종료"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Stop FSNotes"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sair do FSNotes"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sair do FSNotes"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Выход из FSNotes"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes'tan Çık"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Завершити роботу FSNotes"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "退出 FSNotes"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "結束 FSNotes"
}
}
}
},
"4Sj-5v-Clo.placeholderString" : {
"comment" : "Class = \"NSTextFieldCell\"; placeholderString = \"git@github.com:username/repo.git\"; ObjectID = \"4Sj-5v-Clo\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "https://github.com/glushchenko/fsnotes.git"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "git@github.com:uzivatel/repo.git"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "https://github.com/glushchenko/fsnotes.git"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "git@github.com:username/repo.git"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "https://github.com/glushchenko/fsnotes.git"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "https://github.com/glushchenko/fsnotes.git"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "https://github.com/glushchenko/fsnotes.git"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "git@github.com:username/repo.git"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "https://github.com/glushchenko/fsnotes.git"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "https://github.com/glushchenko/fsnotes.git"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "https://github.com/glushchenko/fsnotes.git"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "https://github.com/glushchenko/fsnotes.git"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "git@github.com:username/repo.git"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "https://github.com/glushchenko/fsnotes.git"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "git@github.com:username/repo.git"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "git@github.com:kullanıcıadı/repo.git"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "https://github.com/glushchenko/fsnotes.git"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "https://github.com/glushchenko/fsnotes.git"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "git@github.com:username/repo.git"
}
}
}
},
"5gL-j7-Zq8.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Decrypt\"; ObjectID = \"5gL-j7-Zq8\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "ازالة التشفير"
}
},
"cs" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Odebrat šifrování"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Entschlüsseln"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Decrypt"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Eliminar encriptación"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Supprimer le chiffrement"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הסר הצפנה"
}
},
"hi" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "एन्क्रिप्शन हटाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Decrittografa"
}
},
"ja" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "ロックを解除"
}
},
"ko" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "암호화 해제"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Verwijder versleuteling"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Remover criptografia"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Remover criptografia"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Удалить шифрование"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Şifrelemeyi Kaldır"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Видалити шифрування"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "移除加密"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "解密"
}
}
}
},
"5kV-Vb-QxS.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"About FSNotes\"; ObjectID = \"5kV-Vb-QxS\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "حول FSNotes"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "O aplikaci FSNotes"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Über FSNotes"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "About FSNotes"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Acerca de FSNotes"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "A propos de FSNotes"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "אודות FSNotes"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes के बारे में"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Informazioni su FSNotes"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotesについて"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes에 관하여"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Over FSNotes"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sobre o FSNotes"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Acerca de FSNotes"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Про FSNotes"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes Hakkında"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Про FSNotes"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "关于 FSNotes"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "關於 FSNotes"
}
}
}
},
"5LV-Vi-n79.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Copy Title\"; ObjectID = \"5LV-Vi-n79\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "نسخ العنوان"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kopírovat nadpis"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Title kopieren"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Copy Title"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copiar título"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copier le titre"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "העתק כותרת"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "शीर्षक कॉपी करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copia titolo"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "タイトルをコピー"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "제목 복사"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kopieer titel"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copiar título"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copiar título"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Скопировать заголовок"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Başlığı Kopyala"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Скопіювати заголовок"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "拷贝标题"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "複製標題"
}
}
}
},
"05n-RU-nOV.title" : {
"comment" : "Class = \"NSMenu\"; title = \"Sort By\"; ObjectID = \"05n-RU-nOV\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "ترتيب حسب"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Řadit podle"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sortieren nach"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Sort By"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordenar por"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Trier par"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "מיין לפי"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "इसके अनुसार क्रमबद्ध करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordina per"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "表示順序"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "다음으로 정렬"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sorteer op"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordenar por"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordenar por"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сортировать по"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Göre sırala"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сортувати за"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "排序方式"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "排序方式"
}
}
}
},
"5QF-Oa-p0T.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Edit\"; ObjectID = \"5QF-Oa-p0T\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تعديل"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Upravit"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bearbeiten"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Edit"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Editar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Éditer"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "עריכה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "संपादन"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Modifica"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "編集"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "편집"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Edit"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Editar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Editar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Редактировать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Düzenle"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Редагування"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "编辑"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "編輯"
}
}
}
},
"6AI-tL-TDI.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Hide images preview\"; ObjectID = \"6AI-tL-TDI\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "اخفاء معاينة الصور"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Skrýt náhled obrázků"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bildvorschau ausblenden"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Hide images preview"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ocultar la previsualización de imágenes"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Masquer l'aperçu des images"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הסתר תמונות"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "छवियों का पूर्वावलोकन छिपाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nascondi anteprima immagini"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "画像プレビューを非表示"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "이미지 미리보기 가리기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verberg voorvertoning afbeeldingen"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ocultar pré-visualização das imagens"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ocultar pré-visualização de imagens"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Спрятать превью изображений"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Görüntü önizlemesini gizle"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сховати прев'ю зображень"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "隐藏图像预览"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "隱藏圖片預覽"
}
}
}
},
"6dh-zS-Vam.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Redo\"; ObjectID = \"6dh-zS-Vam\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "استرجاع"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Opakovat akci"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Wiederholen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Redo"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rehacer"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Refaire"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "חזור על הפעולה האחרונה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "फिर से करे"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ripeti"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "やり直し"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "실행 복귀"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Opnieuw doen"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Refazer"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Refazer"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вперёд"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yeniden yap"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Повторити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "重做"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "重做"
}
}
}
},
"6F0-Cb-DVX.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Code Theme:\"; ObjectID = \"6F0-Cb-DVX\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Code ثيم:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Motiv kódu"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Code Design:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Code Theme:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tema:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Theme de code :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "ערכת נושא לקוד:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कोड थीम:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tema grafico del Codice:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "コードテーマ:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "코드 테마:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Code Thema:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tema do código:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tema de código:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Тема для кода:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kod Teması:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Тема коду:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "代码主题:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "程式碼主題:"
}
}
}
},
"7GB-y2-EMo.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Close\"; ObjectID = \"7GB-y2-EMo\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "اغلاق"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zavřít"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Schließen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Close"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cerrar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fermer"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "סגור"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "बंद करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Chiudi"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "閉じる"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "닫기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sluit"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fechar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fechar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Закрыть"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kapat"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Закрити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "关闭"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "關閉"
}
}
}
},
"7iL-1X-EtS.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Clone\"; ObjectID = \"7iL-1X-EtS\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clone"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Klonovat"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clone"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Clone"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clone"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clone"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clone"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "क्लोन"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clone"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clone"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clone"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clone"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clone"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clone"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Склонировать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kopyala"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clone"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "克隆"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "複製專案 (Clone)"
}
}
}
},
"7me-g8-vOq.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Current Password:\"; ObjectID = \"7me-g8-vOq\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "كلمة المرور الحالية:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Současné heslo:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aktuelle Passwort:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Current Password:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Contraseña actual:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mot de passe actuel"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "סיסמה נוכחית:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "वर्तमान पासवर्ड:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Password corrente:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "現在のパスワード:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "기존 암호:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Huidig wachtwoord:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Senha atual"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Palavra-passe actual"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Текущий пароль:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mevcut Şifre:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Поточний пароль:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "当前密码:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "目前密碼:"
}
}
}
},
"7MT-fy-lXN.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Open External\"; ObjectID = \"7MT-fy-lXN\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "فتح خارجي"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Otevřít externí"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "In externem Editor öffnen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Open External"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Abrir externo"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ouvrir en externe"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "פתח חיצוני"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "बाहरी खोलें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Apri esternamente"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "外部エディターで開く..."
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "외부에서 열기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Open extern"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Abrir External"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Abrir externamente"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Внешний редактор"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Açık Harici"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Відкрити зовні"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "打开外部"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "在外部開啟"
}
}
}
},
"7od-TM-cUB.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Set\"; ObjectID = \"7od-TM-cUB\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "مجموعة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nastavit"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Setzen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Set"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Escoger"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Appliquer"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "בחר"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "सेट करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Imposta"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "設定"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "설정"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Instelling"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Definir"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Definir"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Установить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ayarla"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Встановити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "设置"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "設定"
}
}
}
},
"7xA-9l-dja.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Change\"; ObjectID = \"7xA-9l-dja\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "التغيير"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Změnit"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ändern"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Change"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cambiar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Changer"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "שנה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "बदलें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cambia"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "変更"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "변경"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verander"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Alterar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Modificar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Изменить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Değiştir"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Змінити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "更改"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "變更"
}
}
}
},
"8AQ-IN-Edm.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Small\"; ObjectID = \"8AQ-IN-Edm\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "صغير"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Malé"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Klein"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Small"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pequeño"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Petit"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "קטן"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "छोटा"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Piccolo"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "小さい"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "작게"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Klein"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pequeno"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pequeno"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Маленький"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Küçük"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Маленький"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "小"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "小"
}
}
}
},
"8cf-5K-KZh.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Ordered List\"; ObjectID = \"8cf-5K-KZh\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "قائمة مرتبة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Řazený seznam"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bestellliste"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Ordered List"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lista ordenada"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Liste ordonnée"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "רשימה ממוספרת"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "क्रमबद्ध सूची"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lista Ordinata"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "番号付きリスト"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "주문 된 목록"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordered List"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lista ordenada"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "List Ordenada"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Упорядоченный список"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sıralı Liste"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Упорядкований список"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "有序列表"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "編號清單"
}
}
}
},
"8dk-Cf-bSg.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Lock when user switched\"; ObjectID = \"8dk-Cf-bSg\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "قفل عند تحول المستخدم"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zamknout při přepnutí uživatele"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sperren, wenn der Benutzer wechselt"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Lock when user switched"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloquear al cambiar de usuario"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verrouiller au changement d'utilisateur"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "נעל בהחלפת משתמש"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "उपयोगकर्ता बदलने पर लॉक करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Blocca quando viene cambiato utente"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ユーザー切り替え時"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "사용자 변경시 잠금"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vergrendel bij verandering van gebruiker"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloquear quando alterar usuário"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloquear quando alterar utilizador"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заблокировать при смене польз."
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kullanıcı değiştiğinde kilitle"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заблокувати при перемиканні"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "用户切换时自动锁定"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "切換使用者時鎖定"
}
}
}
},
"8om-Y6-O8e.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Credentials:\"; ObjectID = \"8om-Y6-O8e\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "أوراق اعتماد:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Přístupové údaje"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Berechtigungsnachweise:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Credentials:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cartas credenciales:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Identifiants:"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "אישורים:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "साख:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Credenziali:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "資格:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "신임장:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Inloggegevens:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Credenciais:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Credenciais:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Реквизиты для входа:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kimlik Bilgileri:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Облікові дані:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "证书:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "憑證:"
}
}
}
},
"9ic-FL-obx.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Substitutions\"; ObjectID = \"9ic-FL-obx\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "استبدالات"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Záměny"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ersetzungen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Substitutions"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sustituciones"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Substitutions"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "החלפות"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "प्रतिस्थापन"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sostituzioni"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "自動置換"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "대체"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vervangingen"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Substituições"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Substituições"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Замены"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "İkameler"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заміни"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "替换"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "替代"
}
}
}
},
"9pM-sd-qhm.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Port:\"; ObjectID = \"9pM-sd-qhm\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Port:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Port:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Port:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Port:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Port:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Port:"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Port:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पोर्ट:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Port:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Port:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Port:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Port:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Port:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Port:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Порт:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Port:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Порт:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "端口:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "連接埠:"
}
}
}
},
"9w3-fa-di3.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"2/23/11\"; ObjectID = \"9w3-fa-di3\"; Note = \"#bc-ignore!\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "2/23/11"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "2/23/11"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "2/23/11"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "2/23/11"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "2/23/11"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "2/23/11"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
}
},
"shouldTranslate" : false
},
"9yt-4B-nSM.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Smart Copy/Paste\"; ObjectID = \"9yt-4B-nSM\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "نسخ/لصق الذكي"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Inteligentní kopírování/vkládání"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Intelligente Kopieren / Einfügen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Smart Copy/Paste"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copiado/pegado Inteligente"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copier/Coller intelligent"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "העתקה והדבקה חכמות"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "स्मार्ट कॉपी/पेस्ट"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copia/Incolla Smart"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "スマートコピー/ペースト"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "스마트 복사하기/붙여넣기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Slim Kopiëren/Plakken"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copiar/colar inteligente"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copiar/Colar Inteligente"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Смарт-копирование/вставка"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Akıllı Kopyala/Yapıştır"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Розумне копіювання/вставка"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "智能拷贝/粘贴"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "智慧型複製/貼上"
}
}
}
},
"13t-eQ-kOr.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Translators:\"; ObjectID = \"13t-eQ-kOr\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "مترجمين:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Překladatelé"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Translators:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Translators:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Traductores:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Traducteurs :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "מתרגמים:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "अनुवादक:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Traduttori:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "翻訳者:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "번역자:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vertalers:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tradutores:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tradutores:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Переводчики:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tercümanlar:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перекладачі:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "翻译:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "翻譯貢獻者:"
}
}
}
},
"44f-my-fi3.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Passphrase:\"; ObjectID = \"44f-my-fi3\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "عبارة المرور:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Přístupová fráze:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Passprobe:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Passphrase:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Frase de contraseña:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Passphrase:"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "ביטוי סיסמה:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पासफ्रेज:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Frase d'accesso:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Passphrase:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "암호:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Wachtwoordzin:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Frase secreta:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Senha:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Парольная фраза:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Parola:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Кодова фраза:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "密码:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "通關密語:"
}
}
}
},
"63m-us-3j9.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Code Font:\"; ObjectID = \"63m-us-3j9\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "خط الكود:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Písmo kódu:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Code Schrift:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Code Font:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fuente:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Police de code :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "גופן קוד:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कोड फ़ॉन्ट:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Font Codice:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "コードフォント:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "코드 서체:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Code Lettertype:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Código fonte:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Letra de código:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Шрифт кода:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kod Yazı Tipi:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Шрифт коду:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "代码字体:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "程式碼字體:"
}
}
}
},
"78Y-hA-62v.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Correct Spelling Automatically\"; ObjectID = \"78Y-hA-62v\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تصحيح الإملاء تلقائيًا"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Automaticky opravovat pravopis"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rechtschreibung automatisch korrigieren"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Correct Spelling Automatically"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Corregir ortografía automáticamente"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Corriger automatiquement l'orthographe"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "תקן איות באופן אוטומטי"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "वर्तनी स्वतः सही करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Correggi Ortografia Automaticamente"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "スペルを自動的に修正"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "맞춤법 자동 수정"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Corrigeer Spelling Automatisch"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Corrigir ortografia automaticamente"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Corrigir Ortografia Automáticamente"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Автоматическое исправление орфографии"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Otomatik Olarak Doğru Yazımı Düzelt"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Автоматично коригувати правописання"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "自动纠正拼写"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "自動修正拼字"
}
}
}
},
"a1w-ll-Djh.placeholderString" : {
"comment" : "Class = \"NSTextFieldCell\"; placeholderString = \"empty log\"; ObjectID = \"a1w-ll-Djh\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "empty log"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "empty log"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "empty log"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "empty log"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "empty log"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "empty log"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "empty log"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "खाली लॉग"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "empty log"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "empty log"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "empty log"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "empty log"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "log vazio"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "empty log"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "empty log"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Boş Log"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "empty log"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "empty log"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "清空記錄"
}
}
}
},
"A5V-Wm-if2.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Minimize\"; ObjectID = \"A5V-Wm-if2\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تصغير"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Minimalizovat"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Minimieren"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Minimize"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Minimizar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Minimizer"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "מזער"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "छोटा करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Minimizza"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "しまう"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "최소화"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Minimaliseren"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Minimizar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Minimizar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Минимизировать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Küçült"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Приховати"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "最小化"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "縮到最小"
}
}
}
},
"a6n-hz-V8D.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Search shortcut:\"; ObjectID = \"a6n-hz-V8D\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "اختصار البحث:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hledat:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verknüpfung suchen:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Search shortcut:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Función rápida de búsqueda:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Raccourci recherche:"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "קיצור דרך לחפש:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "खोज शॉर्टकट:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ricerca rapida:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "検索ショートカット:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "검색 단축키:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zoek snelkoppeling:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pesquisar atalho:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pesquisar atalho:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Поиск:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Arama kısayolu:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Швидкий пошук:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "搜索快捷方式:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "搜尋快速鍵:"
}
}
}
},
"a9t-hD-WYR.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Host:\"; ObjectID = \"a9t-hD-WYR\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Host:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hostitel:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Host:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Host:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Host:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Host:"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Host:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "होस्ट:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Host:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Host:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Host:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Host:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Host:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Host:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Хост:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Host:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Хост:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "主机Host:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "主機:"
}
}
}
},
"aGv-BR-Oc8.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Upload and test initial data\"; ObjectID = \"aGv-BR-Oc8\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تحميل واختبار البيانات الأولية"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nahrát a otestovat úvodní data"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hochladen und Testen der ersten Daten"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Upload and test initial data"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cargar y probar datos iniciales"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Télécharger et tester les données initiales"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "העלה ובדוק נתונים ראשוניים"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "प्रारंभिक डेटा अपलोड करें और उसका परीक्षण करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Carica e testa i dati iniziali"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "初期データのアップロードとテスト"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "초기 데이터 업로드 및 테스트"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Upload en test initiële gegevens"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Carregar e testar dados iniciais"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Carregar e testar dados iniciais"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Загрузить исходные данные и протестировать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "İlk verileri yükleyin ve test edin"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Завантаження та перевірка вихідних даних"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "上传和测试初始数据"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "上傳並測試初始資料"
}
}
}
},
"aLg-MQ-amx.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Italic:\"; ObjectID = \"aLg-MQ-amx\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kursiv:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Italic:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cursiva:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Italique :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "इतालिक:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Corsivo:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Курсив:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "İtalik:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Курсив:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "斜体:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "斜體:"
}
}
}
},
"ASf-hd-2fT.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Repositories:\"; ObjectID = \"ASf-hd-2fT\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "المستودعات:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Repozitáře:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Repositories:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Repositories:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Repositorios:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dépôts :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "מאגרים:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "रिपोजिटरी:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Repository:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "リポジトリ:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "저장소:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Opslagplaatsen:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Repositórios:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Repositórios:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Репозитории:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Depolar:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Репозиторії:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "存储库:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "儲存庫:"
}
}
}
},
"Atd-Fs-Chq.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Origin:\"; ObjectID = \"Atd-Fs-Chq\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git origin:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Origin:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git origin:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Origin:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git origin:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git origin:"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git origin:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "उद्गम:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git origin:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git origin:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git origin:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git origin:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Origem:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git origin:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git ориджин:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Menşei:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git origin:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git Origin:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "來源 (Origin):"
}
}
}
},
"auW-wa-jbc.title" : {
"comment" : "Class = \"NSMenu\"; title = \"History\"; ObjectID = \"auW-wa-jbc\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تاريخ"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Historie"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Versionsverlauf"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "History"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Historia"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Historique"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "היסטוריה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "इतिहास"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cronologia"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "履歴"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "변경 이력"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Geschiedenis"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Histórico"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Histórico"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "История"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tarih"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Історія"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "笔记历史版本"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "歷程記錄"
}
}
}
},
"aVa-yH-IpC.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Format: yyyyMMddHHmmss\"; ObjectID = \"aVa-yH-IpC\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "التنسيق: yyyyMMddHHmmss"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formát: yyyyMMddHHmmss"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Format: yyyyMMddHHmmss"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Format: yyyyMMddHHmmss"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formato: yyyyMMddHHmmss"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Format: yyyyMMddHHmmss"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "פורמט: yyyyMMddHHmmss"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "प्रारूप: yyyyMMddHHmmss"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formato: yyyyMMddHHmmss"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "フォーマット: yyyyMMddHHmmss"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "체재: yyyyMMddHHmmss"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Format: yyyyMMddHHmmss"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formato: yyyyMMddHHmmss"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formato: yyyyMMddHHmmss"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Формат: yyyyMMddHHmmss"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Biçim: yyyyMMddHHmmss"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Формат: yyyyMMddHHmmss"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "格式: yyyyMMddHHmmss"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "格式:yyyyMMddHHmmss"
}
}
}
},
"aX0-yU-aew.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"iCloud Drive\"; ObjectID = \"aX0-yU-aew\"; Note = \"#bc-ignore!\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "iCloud Drive"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud ड्राइव"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Sürücüsü"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud 雲碟"
}
}
}
},
"axA-pN-Zf2.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Set\"; ObjectID = \"axA-pN-Zf2\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تعيين"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nastavit"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Satz"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Set"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Establecer"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Régler"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Set"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "सेट करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Impostare"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Set"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "세트"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Set"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Definir"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Definir"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Выбрать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ayarla"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вибрати"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "设置"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "設定"
}
}
}
},
"AYu-sK-qS6.title" : {
"comment" : "Class = \"NSMenu\"; title = \"Main Menu\"; ObjectID = \"AYu-sK-qS6\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "القائمة الرئيسية"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hlavní nabídka"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hauptmenü"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Main Menu"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Menú principal"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Menu principal"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Main Menu"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "मुख्य मेन्यू"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Menù principale"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "メインメニュー"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "주 메뉴"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hoofdmenu"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Menu principal"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Menu Principal"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Основное Меню"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ana Menü"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Головне меню"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "主菜单"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "主選單"
}
}
}
},
"B7t-9v-bSk.placeholderString" : {
"comment" : "Class = \"NSSearchFieldCell\"; placeholderString = \"Search or create\"; ObjectID = \"B7t-9v-bSk\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "بحث او انشاء"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hledat / vytvořit"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Suchen oder erstellen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Search or create"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Buscar o crear"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rechercher ou créer"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "חיפוש ויצירה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "खोजें या बनाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cerca o crea"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "検索/新規作成"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "검색 및 추가"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zoek of maak"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pesquisar ou criar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Procurar ou criar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Найти или создать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ara veya oluştur"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Знайти або створити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "搜索或创建(按下回车即可创建)"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "搜尋或新增"
}
}
}
},
"bCL-eg-DgP.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \".md\"; ObjectID = \"bCL-eg-DgP\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : ".md"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : ".md"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : ".md"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : ".md"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : ".md"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : ".md"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : ".md"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : ".md"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : ".md"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : ".md"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : ".md"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : ".md"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : ".md"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : ".md"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : ".md"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : ".md"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : ".md"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : ".md"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : ".md"
}
}
}
},
"bdD-JA-K8P.placeholderString" : {
"comment" : "Class = \"NSTextFieldCell\"; placeholderString = \"/var/www/example.com\"; ObjectID = \"bdD-JA-K8P\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "/var/www/example.com"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "/var/www/priklad.com"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "/var/www/example.com"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "/var/www/example.com"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "/var/www/example.com"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "/var/www/example.com"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "/var/www/example.com"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "/var/www/example.com"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "/var/www/example.com"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "/var/www/example.com"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "/var/www/example.com"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "/var/www/example.com"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "/var/www/example.com"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "/var/www/example.com"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "/var/www/example.com"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "/var/www/example.com"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "/var/www/example.com"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "/var/www/example.com"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "/var/www/example.com"
}
}
}
},
"BHF-CB-P9C.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Change\"; ObjectID = \"BHF-CB-P9C\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تغيير"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Změnit"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ändern"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Change"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cambiar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Changer"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "שנה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "बदलें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cambia"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "変更"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Change"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verander"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Alterar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Modificar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Изменить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Değiştir"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Змінити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "更改"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "變更"
}
}
}
},
"bJC-he-nDV.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Note Font:\"; ObjectID = \"bJC-he-nDV\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "خط الملاحظة:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Písmo poznámky:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notizschrift:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Note Font:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fuente:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Police :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "גופן פתקים:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नोट फ़ॉन्ट:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Font Note:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "フォント:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "노트 서체:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notitie Lettertype:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fonte da nota:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tipo de letra de notas:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Шрифт:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Not Yazı Tipi:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Шрифт:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "笔记字体:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "筆記字體:"
}
}
}
},
"bJv-E9-bwW.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Show icon in dock\"; ObjectID = \"bJv-E9-bwW\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "إظهار الأيقونة في شريط الايقونات "
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zobrazit ikonu v Docku"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Icon in dock anzeigen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Show icon in dock"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar icono en el Dock"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Afficher l'icône dans le Dock"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הצג צלמית ב-Dock"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "डॉक में आइकन दिखाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostra icona nel dock"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dockにアイコンを表示"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dock에서 아이콘 보기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Toon icoon in dock"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar ícone na dock"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostar icone na dock"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показывать иконку в доке"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dock'ta simgeyi göster"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Відображати іконку в док панелі"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "在Dock栏中显示图标"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "在 Dock 中顯示圖示"
}
}
}
},
"BoD-Jy-zeE.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Clear Completed Todos\"; ObjectID = \"BoD-Jy-zeE\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Abgeschlossene Aufgaben löschen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Clear Completed Todos"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Borrar tareas completadas"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Effacer les tâches terminées"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "पूरे हुए कार्य हटाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cancella attività completate"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Очистить выполненные задачи"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tamamlanan Görevleri Temizle"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Очистити виконані завдання"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "清除已完成事项"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "清除已完成的待辦事項"
}
}
}
},
"BOF-NM-1cW.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Preferences…\"; ObjectID = \"BOF-NM-1cW\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "التفضيلات ..."
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Předvolby…"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Einstellungen…"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Preferences…"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Preferencias…"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Préférences…"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "העדפות..."
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "प्राथमिकताएं..."
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Preferenze…"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "環境設定…"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "환경설정..."
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Voorkeuren..."
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Preferências..."
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Preferências..."
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Настройки…"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tercihler…"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Налаштування"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "偏好设置…"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "偏好設定…"
}
}
}
},
"Bri-cl-z86.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"minutes\"; ObjectID = \"Bri-cl-z86\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "الدقائق"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "minut po celé"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "minutes"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "minutes"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "minuto"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "minutes"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "דקות"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "मिनट"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "minuti"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "分"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "분에 실행"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "minuten"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "minutos"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "minutos"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "минуту часа"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "dakikalar"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "хвилин"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "分钟"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "分鐘"
}
}
}
},
"BtV-Z4-7Vq.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Move Down in the Notes List\"; ObjectID = \"BtV-Z4-7Vq\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تحرك لأسفل في قائمة الملاحظات"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Posunout dolů v seznamu poznámek"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "In der Notizliste nach unten gehen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Move Down in the Notes List"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mover abajo en la lista de notas"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Note suivante"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "עבור למטה ברשימת הפתקים"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नोट्स सूची में नीचे जाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Muovi in basso nella Lista Note"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "下に移動"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "메모 목록에서 아래로 이동"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Move Down In The Notes List"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mover para baixo na lista de notas"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Descer na lista de Notas"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перейти вниз в списке заметок"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notlar Listesinde Aşağıya Git"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перейти вниз у списку нотаток"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "在笔记列表中下移"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "在筆記清單中下移"
}
}
}
},
"buJ-ug-pKt.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Use Selection for Find\"; ObjectID = \"buJ-ug-pKt\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "استخدم التحديد للبحث"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hledat výběr"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Auswahl suchen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Use Selection for Find"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Usar selección para buscar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Utiliser la sélection pour Rechercher"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "השתמש במלל הנבחר לחיפוש"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "खोजने के लिए चयन का उपयोग करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Usa Selezione per Trovare"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "選択部分を検索に使用"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "선택 부분으로 찾기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Gebruik selectie voor Zoeken"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Usar seleção para procurar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Utilizar selecção para Procura"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Использовать выбранное для поиска"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Seçimi Bulmak İçin Kullan"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Використати вибране для пошуку"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "使用选择查找"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "使用選取範圍進行尋找"
}
}
}
},
"bUL-WS-rIS.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Publish notes to:\"; ObjectID = \"bUL-WS-rIS\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "انشر الملاحظات على:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zveřejnit poznámky na:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Veröffentlichen Sie Notizen an:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Publish notes to:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Publicar notas sobre:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Publier des notes sur:"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "פרסם הערות על:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नोट प्रकाशित करें:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pubblica note su:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "以下に関するメモを公開します。"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "다음에 대한 메모 게시:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Publiceer notities over:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Publicar notas para:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Publicar notas para:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Публиковать заметки на:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notları şuraya yayınla:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Публікувати нотатки на:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "发布笔记到:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "發布筆記至:"
}
}
}
},
"BX0-nb-tVk.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Untagged\"; ObjectID = \"BX0-nb-tVk\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "بدون علامات"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Neoznačené"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ungetaggt"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Untagged"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sin etiquetar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sans libellé"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "ללא תגים"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "बिना टैग"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Note senza Tag"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "タグ無し"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "태그가 없는"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Niet gelabeld"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sem tag"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sem tag"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Без тегов"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Etiketsiz"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Без тегів"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "无标签"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "未加標籤"
}
}
}
},
"bXK-wP-sZc.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Note List Spacing:\"; ObjectID = \"bXK-wP-sZc\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "التباعد في قائمة الملاحظات"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rozestup v seznamu poznámek:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Listenhöhe:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Note List Spacing:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Espaciado en la lista:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Espacement :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "מרווח רשימות פתקים:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नोट सूची रिक्ति:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Spaziatura elenco note:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ノートリストのマージン:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "노트 목록 간격:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notitie lijst spatiëring:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Espaçamento da lista de notas:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Espaçamento da lista:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Высота в списке:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Not Listesi Aralığı:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Відстань між нотатками:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "笔记列表间距:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "筆記清單間距:"
}
}
}
},
"c8a-y6-VQd.title" : {
"comment" : "Class = \"NSMenu\"; title = \"Transformations\"; ObjectID = \"c8a-y6-VQd\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "التحولات"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Transformace"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Transformations"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Transformations"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Transformaciones"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Transformations"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "המרות"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "परिवर्तने"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Trasformazioni"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "変換"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "변형"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Transformaties"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Transformações"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Transformações"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Трансформация"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dönüşümler"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Трансформація"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "转换"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "轉換"
}
}
}
},
"cfe-sv-2gm.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Official Site\"; ObjectID = \"cfe-sv-2gm\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "الموقع الرسمي"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Oficiální stránka"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Offizielle Seite"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Official Site"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sitio web de FSNotes"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Site officiel"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "אתר רשמי"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "आधिकारिक साइट"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sito ufficiale"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "公式サイト"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "공식 사이트"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Officiële site"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Site oficial"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Site oficial"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Официальный сайт"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Resmi Site"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Офіційна сторінка"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "官方网址"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "官方網站"
}
}
}
},
"cmH-fQ-bVK.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Format: UUID\"; ObjectID = \"cmH-fQ-bVK\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "UUID"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formát: UUID"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "UUID"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Format: UUID"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "UUID"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "UUID"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "פורמט: UUID"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "प्रारूप: UUID"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "UUID"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "フォーマット: UUID"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "UUID"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "UUID"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formato: UUID"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "UUID"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "UUID"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Biçim: UUID"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "UUID"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "UUID"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "格式:UUID"
}
}
}
},
"cq7-SM-dez.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Header 6\"; ObjectID = \"cq7-SM-dez\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "عنوان ٦"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nadpis 6"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Header 6"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Header 6"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Encabezado 6"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Titre 6"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "כותרת 6"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "हेडर 6"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Intestazione 6"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ヘッダー 6"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Header 6"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kop 6"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cabeçalho 6"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cabeçalho 6"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заголовок 6"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Başlık 6"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заголовок 6"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "6级标题"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "標題 6"
}
}
}
},
"cQ8-sF-a4g.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Remove\"; ObjectID = \"cQ8-sF-a4g\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remove"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Odebrat"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remove"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Remove"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remove"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remove"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remove"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "हटाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remove"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remove"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remove"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remove"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remover"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remove"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Удалить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kaldır"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remove"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remove"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "移除"
}
}
}
},
"ctD-Qn-kDS.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Format:\"; ObjectID = \"ctD-Qn-kDS\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تنسيق:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formát:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Format:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Format:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formato:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Format :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "פורמט:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "प्रारूप:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formato:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "フォーマット:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "형식:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formaat:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formato:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formato:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Расширение:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Biçim:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Розширення:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "编辑器格式:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "格式:"
}
}
}
},
"cUI-cw-eo5.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Big\"; ObjectID = \"cUI-cw-eo5\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "كبير"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Velké"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Groß"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Big"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Grande"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Grand"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "גדול"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "बड़ा"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Grande"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "大きい"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "크게"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Groot"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Grande"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Grande"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Большой"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Büyük"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Великий"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "较大"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "大"
}
}
}
},
"CvG-Kp-kdK.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Move\"; ObjectID = \"CvG-Kp-kdK\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "نقل"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Přesunout"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verschieben"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Move"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mover"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Déplacer"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "העבר"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "स्थानांतरण"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sposta"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "移動"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "이동"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verplaats"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mover"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mover"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Переместить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Taşı"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перемістити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "移动"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "移動"
}
}
}
},
"cwL-P1-jid.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Smart Links\"; ObjectID = \"cwL-P1-jid\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "روابط ذكية"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Inteligentní odkazy"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Intelligente Links"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Smart Links"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Enlaces inteligentes"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Liens intelligents"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "קישורים חכמים"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "स्मार्ट लिंक"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Link Smart"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "スマートリンク"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "스마트 링크"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Slimme Links"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Links inteligentes"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ligações Inteligentes"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Смарт-ссылки"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Akıllı Bağlantılar"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Розумні посилання"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "智能链接"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "智慧型連結"
}
}
}
},
"cYB-6U-8ac.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Header 2\"; ObjectID = \"cYB-6U-8ac\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "عنوان ٢"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nadpis ě"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Header 2"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Header 2"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Encabezado 2"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Titre 2"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "כותרת 2"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "हेडर 2"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Intestazione 2"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ヘッダー 2"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Header 2"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kop 2"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cabeçalho 2"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cabeçalho 2"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заголовок 2"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Başlık"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заголовок 2"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "2级标题"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "標題 2"
}
}
}
},
"d9M-CD-aMd.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Make Lower Case\"; ObjectID = \"d9M-CD-aMd\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "اجعله حروف صغيرة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Převést na malá písmena"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kleinschreiben"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Make Lower Case"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Todo en minúsculas"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Passer en minuscules"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הפוך לאותיות קטנות"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "लोअर केस बनाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rendi tutto Minuscolo"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "小文字にする"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "소문자로 만들기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Maak kleine letters"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tornar minúsculas"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Transformar em minúsculas"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перевести в нижний регистр"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Küçük Harf Yap"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Нижній регістр"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "转换为小写"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "變更為小寫"
}
}
}
},
"dCc-l5-XB2.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Modification Date\"; ObjectID = \"dCc-l5-XB2\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تاريخ التعديل"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Datum změny"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Änderungsdatum"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Modification Date"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fecha de modificación"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Date de modification"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "תאריך שינוי"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "सुधार की तारीख"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Data di modifica"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "変更日"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "수정일"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Wijzigingsdatum"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Data de modificação"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Data de modificação"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Дата модификации"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Değişiklik Tarihi"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Датою модифікації"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "修改日期"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "修改日期"
}
}
}
},
"DCh-5P-PZe.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Hide/Show Sidebar\"; ObjectID = \"DCh-5P-PZe\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "إخفاء / إظهار الشريط الجانبي\n"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Skrýt/zobrazit boční panel"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Seitenleiste ein/ausblenden"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Hide/Show Sidebar"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar/ocultar barra lateral"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Masquer/Afficher la barre latérale"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הסתר/הצג סרגל צד"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "साइडबार छिपाएँ/दिखाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nascondi/Mostra sidebar"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "サイドバーを表示/非表示"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "사이드바 숨기기/보기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verbergen/tonen zijbalk"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ocultar/mostrar menu lateral"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ocultar/mostrar barra lateral"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Спрятать/показать сайдбар"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kenar Çubuğunu Gizle/Göster"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Приховати/показати сайдбар"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "隐藏/显示侧边栏"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "隱藏/顯示側邊欄"
}
}
}
},
"DcN-1g-hEi.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Medium\"; ObjectID = \"DcN-1g-hEi\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "متوسط"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Střední"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mittel"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Medium"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mediano"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Moyen"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "בינוני"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "मध्यम"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Medio"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "普通"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "보통"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Medium"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Médio"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Médio"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Средний"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Orta"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Середній"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "中等的"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "中"
}
}
}
},
"DeU-hy-pvi.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Shift Left\"; ObjectID = \"DeU-hy-pvi\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تحول اليسار"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Posunout doleva"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Text nach links bewegen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Shift Left"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tabular a la izquierda"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Décaler vers la gauche"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הזחה שמאלה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "बाईं ओर शिफ्ट करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sposta a sinistra"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "左にシフト"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "들여쓰기 삭제"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verschuif Links"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mover para direita"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Deslocar à Esquerda"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сдвиг влево"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sola kaydır"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Зміщення вліво"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "左移"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "向左位移"
}
}
}
},
"dgD-xe-DVG.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"v2.9.0\"; ObjectID = \"dgD-xe-DVG\"; Note = \"#bc-ignore!\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "v2.9.0"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "v2.9.0"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "v2.9.0"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "v2.9.0"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "v2.9.0"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "v2.9.0"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "v2.9.0"
}
}
}
},
"doI-Mu-yZG.placeholderString" : {
"comment" : "Class = \"NSTextFieldCell\"; placeholderString = \"no key\"; ObjectID = \"doI-Mu-yZG\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "no key"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "bez klíče"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "no key"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "no key"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "no key"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "no key"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "no key"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कोई चाबी नहीं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "no key"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "no key"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "no key"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "no key"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "no key"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "no key"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "ключ не выбран"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "no key"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "no key"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "no key"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "無金鑰"
}
}
}
},
"dop-ho-N26.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Separate .git in project dir (except iCloud Drive)\"; ObjectID = \"dop-ho-N26\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Separate .git in project dir (except iCloud Drive)"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Oddělený .git soubor ve složce projektu (kromě iCloud Drive)"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Separate .git in project dir (except iCloud Drive)"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Separate .git in project dir (except iCloud Drive)"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Separate .git in project dir (except iCloud Drive)"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Separate .git in project dir (except iCloud Drive)"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Separate .git in project dir (except iCloud Drive)"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "प्रोजेक्ट निर्देशिका से .git अलग करे (iCloud ड्राइव को छोड़कर)"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Separate .git in project dir (except iCloud Drive)"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Separate .git in project dir (except iCloud Drive)"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Separate .git in project dir (except iCloud Drive)"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Separate .git in project dir (except iCloud Drive)"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Separate .git in project dir (except iCloud Drive)"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Separate .git in project dir (except iCloud Drive)"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : ".git в каталоге проекта (кроме iCloud Drive)"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Proje dizininde .git'i ayırın (iCloud Drive hariç)"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Separate .git in project dir (except iCloud Drive)"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "在项目目录中分隔.git (iCloud 除外)"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "在專案目錄中分離 .git(iCloud 雲碟除外)"
}
}
}
},
"Dp7-4n-ilt.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Custom Server\"; ObjectID = \"Dp7-4n-ilt\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "خادم مخصص"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vlastní server"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Benutzerdefinierter Server"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Custom Server"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Servidor personalizado"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Serveur personnalisé"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "שרת מותאם אישית"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कस्टम सर्वर"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Server personalizzato"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "カスタムサーバー"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "커스텀 서버"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aangepaste server"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Servidor personalizado"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Servidor personalizado"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Пользовательский сервер"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Özel Sunucu"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Користувацький сервер"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "自定义服务器"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "自訂伺服器"
}
}
}
},
"dqy-22-ETG.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Decrypt Folder\"; ObjectID = \"dqy-22-ETG\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "تشفير المجلد"
}
},
"cs" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Zašifrovat složku"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordner entschlüsseln"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Decrypt Folder"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cifrar carpeta"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Crypter le dossier"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הצפנת תיקיה"
}
},
"hi" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "फ़ोल्डर एन्क्रिप्ट करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Decrittografa cartella"
}
},
"ja" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "フォルダの暗号化"
}
},
"ko" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "폴더 암호화"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Map versleutelen"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Criptografar pasta"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Criptografar pasta"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Зашифровать директорию"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Klasörü Şifrele"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Розшифрувати директорію"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "加密文件夹"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "解密資料夾"
}
}
}
},
"dRJ-4n-Yzg.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Undo\"; ObjectID = \"dRJ-4n-Yzg\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تراجع"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Odvolat akci"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rückgängig machen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Undo"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Deshacer"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Annuler"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "ביטול"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पूर्ववत"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Indietro"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "取り消す"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "실행 취소"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ongedaan maken"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Desfazer"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Desfazer"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Отменить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Geri al"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Відмінити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "撤销"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "復原"
}
}
}
},
"Dv1-io-Yv7.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Spelling and Grammar\"; ObjectID = \"Dv1-io-Yv7\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "التهجئة والقواعد اللغوية"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pravopis a gramatika"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rechtschreibung und Grammatik"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Spelling and Grammar"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ortografía y gramática"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Orthographe et grammaire"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "איות ודקדוק"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "वर्तनी और व्याकरण"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ortografia e Grammatica"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "スペルと文法"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "맞춤법 및 문법"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Spelling en Grammatica"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ortografia e Gramática"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ortografia e Gramática"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Орфография и грамматика"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yazım ve Dilbilgisi"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Орфографія і граматика"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "拼写和语法"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "拼字與文法"
}
}
}
},
"DWe-bx-jfM.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Header 5\"; ObjectID = \"DWe-bx-jfM\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "عنوان ٥"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nadpis 5"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Header 5"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Header 5"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Encabezado 5"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Titre 5"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "כותרת 5"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "हेडर 5"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Intestazione 5"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ヘッダー 5"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Header 5"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kop 5"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cabeçalho 5"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cabeçalho 5"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заголовок 5"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Başlık 5"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заголовок 5"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "5级标题"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "標題 5"
}
}
}
},
"DXE-kd-1X3.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Password:\"; ObjectID = \"DXE-kd-1X3\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "كلمة المرور:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Heslo:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kennwort:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Password:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clave:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mot de passe:"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "סיסמה:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पासवर्ड:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Parola d'ordine:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "パスワード:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "비밀번호:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Wachtwoord:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Senha:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Senha:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Пароль:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Şifre :"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Пароль:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "密码"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "密碼:"
}
}
}
},
"dZD-Db-KHs.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Language:\"; ObjectID = \"dZD-Db-KHs\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "اللغة (تحتاج إلى إعادة تشغيل التطبيق):"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Jazyk:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sprache (Neustart erforderlich):"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Language:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Idioma (requiere reiniciar):"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Langue (redémarrage de l'app) :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "שפה (דורש אתחול):"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "भाषा:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lingua:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "言語 (再起動後に反映):"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "언어 (재시작 필요)"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Taal (start app opnieuw op):"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Idioma:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Idioma (reinicia a aplicação)"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Язык (требуется перезапуск):"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dil :"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Мова (потрібен перезапуск):"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "语言 (需要重启FSNotes):"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "語言:"
}
}
}
},
"e0G-y0-N0C.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Todo\"; ObjectID = \"e0G-y0-N0C\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "قائمة المهام"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Úkoly"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Todo"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Todo"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pendientes"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tâches"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "מטלות"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "टुडू"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Da Fare"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "タスク"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "할 일"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Te Doen"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "A fazer"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tarefa"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Задачи"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yapılacaklar"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Завдання"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "待办事项"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "待辦事項"
}
}
}
},
"E1U-fG-XBw.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"SSH configuration:\"; ObjectID = \"E1U-fG-XBw\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "SSH ترتيب:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "SSH konfigurace:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "SSH-Konfiguration:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "SSH configuration:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "SSH configuración:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Paramétrage SSH:"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "SSH תְצוּרָה:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "SSH कॉन्फ़िगरेशन:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Configurazione SSH:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "SSH 構成:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "SSH 구성:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "SSH configuratie:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "SSH configuração:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "SSH configuração:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Конфигурация SSH:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "SSH yapılandırması:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "SSH конфігурація:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "SSH 配置:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "SSH 設定:"
}
}
}
},
"E6I-n5-dsi.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Duplicate\"; ObjectID = \"E6I-n5-dsi\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "عمل نسخة مكررة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Duplikovat"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Duplizieren"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Duplicate"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Duplicar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dupliquer"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "שכפל"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नकल"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Duplica"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "複製"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "복제"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dupliceren"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Duplicar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Duplicar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Создать копию"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kopyala"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Дублювати"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "副本"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "製作複本"
}
}
}
},
"e7y-7Z-36y.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"_\"; ObjectID = \"e7y-7Z-36y\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "_"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "_"
}
}
},
"shouldTranslate" : false
},
"e15-ps-th1.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Hide date\"; ObjectID = \"e15-ps-th1\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "اخفاء التاريخ"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Skrýt datum"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Datum ausblenden"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Hide date"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ocultar la fecha"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Masquer la date"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הסתר תאריך"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "तारीख छुपाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nascondi data"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "日付を非表示"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "날짜 숨기기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verberg datum"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ocultar data"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ocultar data"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Спрятать дату"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tarihi gizle"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сховати дату"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "隐藏日期"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "隱藏日期"
}
}
}
},
"EC3-YF-sGZ.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Preview\"; ObjectID = \"EC3-YF-sGZ\"; Note = \"#bc-ignore!\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Náhled"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Preview"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पूर्वावलोकन"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Önizleme"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Попередній перегляд"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
}
},
"shouldTranslate" : false
},
"eCt-xc-KgN.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Share\"; ObjectID = \"eCt-xc-KgN\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Teilen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Share"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Compartir"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Partager"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "साझा करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Condividi"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Поделиться"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Paylaş"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Поділитися"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "分享"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "分享"
}
}
}
},
"egX-yM-Suq.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Path:\"; ObjectID = \"egX-yM-Suq\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Path:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cesta:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pfad:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Path:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Path:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Path:"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Path:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पथ:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sentiero:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Path:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Path:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Path:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Caminho:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Path:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Путь:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yol:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Шлях:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "路径:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "路徑:"
}
}
}
},
"Ehk-CU-fbX.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Set\"; ObjectID = \"Ehk-CU-fbX\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "مجموعة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nastavit"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Setzen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Set"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Escoger"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Appliquer"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "בחר"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "सेट करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Imposta"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "設定"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "설정"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Instelling"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Definir:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Definir"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Установить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ayarla"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Встановити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "设置"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "設定"
}
}
}
},
"EK1-kN-kK3.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Strikethrough\"; ObjectID = \"EK1-kN-kK3\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "نص يتوسطه خط"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Přeškrtnuté"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Durchgestrichen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Strikethrough"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tachado"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Barrer"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "קו חוצה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "स्ट्राइकथ्रू"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Barrato"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "取り消し線"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "취소선"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Doorhalen"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Riscar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Suprimir"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перечёркнутый"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Üstü çizili"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перекреслений"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "删除线"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "刪除線"
}
}
}
},
"eKQ-lM-8Z4.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Font preview\"; ObjectID = \"eKQ-lM-8Z4\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "معاينة الخط"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Náhled písma"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Font Vorschau"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Font preview"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Font preview"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aperçu de la police"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "תצוגת גופן"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "फ़ॉन्ट पूर्वावलोकन"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Anteprima Font"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "フォントプレビュー"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "서체 미리보기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lettertype voorvertoning"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pré-visualização da fonte"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pré-visualizar tipo de letra"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Предпросмотр шрифта"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yazı tipi önizlemesi"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Шрифт попереднього перегляда"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "字体预览"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "字體預覽"
}
}
}
},
"ELw-Y4-DV0.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Version\"; ObjectID = \"ELw-Y4-DV0\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "الاصدار"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verze"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Version"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Version"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Versión"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Version"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "גרסה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "संस्करण"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Versione"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "バージョン"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "버전"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Versie"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Versão"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Versão"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Версия"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Versiyon"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Версія"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "版本"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "版本"
}
}
}
},
"eTL-dh-GvM.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Creation Date\"; ObjectID = \"eTL-dh-GvM\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تاريخ الانشاء"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Datum vytvoření"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Erstellungsdatum"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Creation Date"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fecha de creación"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Date de création"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "תאריך יצירה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "निर्माण तारीख"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Data di creazione"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "作成日"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "생성일"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aanmaakdatum"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Data de criação"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Data de criação"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Дата создания"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Oluşturulma Tarihi"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Датою створення"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "创建日期"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "建立日期"
}
}
}
},
"EYG-WM-BFN.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Ascending\"; ObjectID = \"EYG-WM-BFN\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تصاعدي"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vzestupně"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aufsteigend"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Ascending"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ascendente"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ascendant"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "עולה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "आरोही"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Crescente"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "昇順"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "오름차순"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Oplopend"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ascendente"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ascendente"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Восходящее"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yükselen"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Висхідний"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "升序"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "遞增"
}
}
}
},
"F2S-fz-NVQ.title" : {
"comment" : "Class = \"NSMenu\"; title = \"Help\"; ObjectID = \"F2S-fz-NVQ\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "مساعدة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nápověda"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hilfe"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Help"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ayuda"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aide"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "עזרה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "सहायता"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aiuto"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ヘルプ"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "도움말"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Help"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ajuda"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ajuda"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Помощь"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yardım"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Допомога"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "帮助"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "輔助說明"
}
}
}
},
"F6G-ua-MNX.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Hide preview\"; ObjectID = \"F6G-ua-MNX\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "اخفاء المعاينة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Skrýt náhled textu"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vorschau ausblenden"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Hide preview"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ocultar la previsualización de notas"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Masquer l'apercu"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הסתר תצוגה מקדימה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पूर्वावलोकन छुपाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nascondi anteprima note"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "リストプレビューを非表示"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "미리보기 숨기기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verberg voorvertoning"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ocultar pré-visualização"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ocultar pré-visualização"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Отключить предпросмотр"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Önizlemeyi gizle"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сховати прев'ю"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "隐藏预览"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "隱藏預覽"
}
}
}
},
"f33-1h-Hvh.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Show nested folders content\"; ObjectID = \"f33-1h-Hvh\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "إظهار محتوى المجلدات المتداخلة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zobrazit obsah podsložek"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Show nested folders content"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Show nested folders content"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar el contenido de las carpetas anidadas"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Afficher le contenu sous-jacent"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הצג תכני תיקיה מקוננים"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नेस्टेड फ़ोल्डर्स सामग्री दिखाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostra il contenuto delle cartelle"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "深い階層にあるフォルダの内容も表示"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "중첩 폴더 콘텐츠 표시"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Show nested folders content"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar conteúdo das pastas aninhadas"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostarr conteúdo das pastas contíguas"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показывать содержимое подпапок"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "İç içe klasörlerin içeriğini göster"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показувати вміст підпапок"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "显示嵌套文件夹内容"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "顯示巢狀資料夾內容"
}
}
}
},
"FeM-D8-WVr.title" : {
"comment" : "Class = \"NSMenu\"; title = \"Substitutions\"; ObjectID = \"FeM-D8-WVr\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تبديلات"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Záměny"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ersetzungen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Substitutions"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sustituciones"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Substitutions"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "החלפות"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "प्रतिस्थापन"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sostituzioni"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "自動置換"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "대체"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vervangingen"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Substituições"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Substituições"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Подстановка"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "İkameler"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заміни"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "替换"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "替代"
}
}
}
},
"fHG-zk-g0k.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Delete\"; ObjectID = \"fHG-zk-g0k\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "حذف"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Smazat"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Löschen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Delete"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Eliminar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Supprimer"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "מחק"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "मिटाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Elimina"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "削除"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "삭제"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verwijder"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Deletar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Eliminar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Удалить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sil"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Видалити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "删除"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "刪除"
}
}
}
},
"FKE-Sm-Kum.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"FSNotes Help\"; ObjectID = \"FKE-Sm-Kum\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes مساعدة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nápověda pro FSNotes"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes Hilfe"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "FSNotes Help"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ayuda de FSNotes"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aide de FSNotes"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "עזרה בנושא FSNotes"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes सहायता"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Guida di FSNotes"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotesヘルプ"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes 도움말"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes-hulp"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ajuda do FSNotes"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ajuda do FSNotes"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Помощь FSNotes"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes Yardım"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Допомога FSNotes "
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes帮助"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes 輔助說明"
}
}
}
},
"FKf-Ph-LiA.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Icons design:\"; ObjectID = \"FKf-Ph-LiA\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تصميم الأيقونات:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Design ikon:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Icons design:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Icons design:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Icons design:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Design des icônes :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "עיצוב צלמיות:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "चिह्न डिजाइन:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Design icone:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "アイコンデザイン:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "아이콘 디자인:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pictogrammen ontwerp:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Design dos ícones:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Design dos ícones:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Дизайн иконки:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Simge tasarımı:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Дизайн іконок:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "图标设计:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "圖示設計:"
}
}
}
},
"fkH-Wf-n87.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Decrypt\"; ObjectID = \"fkH-Wf-n87\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "ازالة التشفير"
}
},
"cs" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Odebrat šifrování"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Entschlüsseln"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Decrypt"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Quitar encriptación"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Supprimer le chiffrement"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הסר הצפנה"
}
},
"hi" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "एन्क्रिप्शन हटाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Decrittografa"
}
},
"ja" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "ロックを削除"
}
},
"ko" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "암호화 해제"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Verwijder versleuteling"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Remover criptografia"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Remover criptografia"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Снять шифрование"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Şifrelemeyi Kaldır"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Розшифрувати нотатку"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "移除加密"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "解密"
}
}
}
},
"fmS-eE-nne.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Default Storage:\"; ObjectID = \"fmS-eE-nne\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "الخزن الافتراضي:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Výchozí úložiště"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Standardspeicherort:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Default Storage:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Almacenamiento por defecto:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Stockage par défaut:"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "אחסון ברירת מחדל:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "डिफ़ॉल्ट संग्रहण:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Storage predefinito:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "デフォルトストレージ:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "기본 저장소:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Standaard opslag:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Armazenamento padrão:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Armazenamento por defeito:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Хранилище по умолчанию:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Varsayılan Depolama:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Розташування за замовчуванням:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "默认存储:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "預設儲存空間:"
}
}
}
},
"FQV-5x-ffs.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Zoom\"; ObjectID = \"FQV-5x-ffs\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تقريب"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Přiblížení"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zoomen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Zoom"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zoom"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zoom"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הגדל/הקטן"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "ज़ूम"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zoom"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "拡大"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "확대"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zoom"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zoom"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zoom"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Увеличить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yakınlaştır"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Наблизити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "缩放"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "縮放"
}
}
}
},
"frt-CF-STi.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Change\"; ObjectID = \"frt-CF-STi\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تغيير"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Změnit"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ändern"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Change"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cambiar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Changer"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "שנה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "बदलें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cambia"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "変更"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "변경"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verander"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Alterar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Alterar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Изменить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Değiştir"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Змінити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "更改"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "變更"
}
}
}
},
"FS0-ZJ-WvJ.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Files Naming:\"; ObjectID = \"FS0-ZJ-WvJ\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تسمية الملفات:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pojmenování souborů:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Benennung der Dateien:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Files Naming:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nombre de archivos:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nommage des fichiers:"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "שם קבצים:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "फ़ाइल नामकरण:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Denominazione dei file:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ファイル名:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "파일 이름 지정:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bestandsnaamgeving:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nomenclatura dos arquivos:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nomenclatura de ficheiros:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Именование файлов:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dosya Adlandırma:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Іменування файлів:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "文件命名中:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "檔案命名:"
}
}
}
},
"fsF-5N-tWg.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Made with ❤️ in Ukraine 🇺🇦 \"; ObjectID = \"fsF-5N-tWg\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "مصنوع من ❤️ في أوكرانيا 🇺🇦 "
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vytvořeno s ❤️ v Ukrajině 🇺🇦 "
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hergestellt mit ❤️ in der Ukraine 🇺🇦"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Made with ❤️ in Ukraine 🇺🇦 "
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hecho con ❤️ en Ucrania 🇺🇦 "
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fait avec ❤️ en Ukraine 🇺🇦 "
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "נבנה ב-❤️ באוקראינה 🇺🇦"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "यूक्रेन 🇺🇦 में ❤️ के साथ बनाया गया"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Realizzato con ❤️ in Ucraina 🇺🇦 "
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ウクライナで❤️を使って作られました🇺🇦"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "우크라이나에서 ❤️으로 만든 🇺🇦"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Gemaakt met ❤️ in Ukraine 🇺🇦 "
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Feito com ❤️ na Ucrânia 🇺🇦"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Feito com ❤️ na Ucrânia 🇺🇦"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сделано с ❤️ в Украине 🇺🇦"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ukrayna'da ❤️ ile yapıldı 🇺🇦"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Зроблено з ❤️ в Україні 🇺🇦"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "乌克兰 ❤️ 制造 🇺🇦 "
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "來自烏克蘭的 ❤️ 製作"
}
}
}
},
"fzU-ZR-Ubv.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Rename Folder\"; ObjectID = \"fzU-ZR-Ubv\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تسمية المجلد"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Přejmenovat složku"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordner umbenennen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Rename Folder"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renombar carpeta"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renommer le dossier"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "שנה שם תיקיה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "फ़ोल्डर का नाम बदलें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rinomina cartella"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "フォルダの名称変更"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "폴더 이름 변경"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hernoem map"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renomear pasta"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renomear pasta"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Переименовать директорию"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Klasörü Yeniden Adlandır"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перейменувати директорію"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "重命名文件夹"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "重新命名資料夾"
}
}
}
},
"fzY-c6-DaK.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Auto-lock for Encrypted Notes:\"; ObjectID = \"fzY-c6-DaK\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "القفل التلقائي للملاحظات المشفرة:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Automaticky zamykat šifrované poznámky:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Automatische Sperre für verschlüsselte Notizen:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Auto-lock for Encrypted Notes:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloquear autómaticamente las notas encriptadas:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verrouiller automatiquement les notes chiffrées :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "נעילה אוטומטית לפתקים מוצפנים:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "एन्क्रिप्टेड नोट्स के लिए स्वतः लॉक:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Blocco automatico per note cifrate:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ロックされたノートを自動で閉じる:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "암호화된 노트 자동 잠금:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Automatisch vergrendelen voor versleutelde notities:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloquear automaticamente notas criptografadas:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloquear automático para notas criptografadas:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Автоблокировка:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Şifreli Notlar için Otomatik Kilit:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Авто-блокування:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "自动锁定加密的笔记:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "加密筆記自動鎖定:"
}
}
}
},
"g5W-YF-jAC.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Scan inline tags\"; ObjectID = \"g5W-YF-jAC\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "مسح العلامات المضمنة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Detekovat značky v textu"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Scan inline tags"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Scan inline tags"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Escanear etiquetas automáticamente"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Balayer les tags en ligne"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "סרוק תגים מוטבעים"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "इनलाइन टैग स्कैन करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Scansiona i tag in linea"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "インラインタグをスキャンする"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "인라인 태그 스캔"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Inline-tags scannen"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Escanear tags inline"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Examinar etiquetas em linha"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сканировать встроенные теги"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Satır içi etiketleri tarayın"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cканувати вбудовані теги"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "扫描内联标签"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "掃描行內標籤"
}
}
}
},
"gbE-yH-ECm.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Save clipboard shortcut:\"; ObjectID = \"gbE-yH-ECm\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "حفظ اختصار الحافظة:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vytvořit ze schránky:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aus Zwischenablage kopieren:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Save clipboard shortcut:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "F. rápida guardar portapapeles:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sauvegarder le presse-papier :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "קיצור דרך לשמור את לוח העריכה:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "क्लिपबोर्ड सहेजें शॉर्टकट:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Salva appunti in una nuova nota:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "クリップボードから新規作成:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "클립보드 저장 단축키:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Opslaan klembord-snelkoppeling"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Salvar atalho na área de transferência"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Guardar no 'clipboard':"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сохранить из буфера:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Panoya kaydetme kısayolu:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Швидке збереження:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "保存剪贴板快捷方式:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "儲存剪貼簿快速鍵:"
}
}
}
},
"Gbf-V7-5Ra.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"seconds\"; ObjectID = \"Gbf-V7-5Ra\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "ثواني"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "sekund"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "seconds"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "seconds"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "seconds"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "seconds"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "שניות"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "seconds"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "seconds"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "seconds"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "seconds"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "seconds"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "segundos"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "seconds"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "секунды"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "saniyeler"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "seconds"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "秒"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "秒"
}
}
}
},
"GCG-C6-9cg.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Modification date\"; ObjectID = \"GCG-C6-9cg\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تاريخ التعديل"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Datum změny"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Änderungsdatum"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Modification date"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fecha de modificación"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Date de modification"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "תאריך שינוי"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "सुधार की तारीख"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Data di modifica"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "変更日"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "수정일"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Wijzigingsdatum"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Data de modificação"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Data de modificação"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Дата модификации"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Değişiklik tarihi"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Датою модифікації"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "修改日期"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "修改日期"
}
}
}
},
"GcP-oI-0b4.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Cancel\"; ObjectID = \"GcP-oI-0b4\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "الغاء"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zrušit"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Abbrechen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Cancel"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cancelar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Annuler"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "ביטול"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "रद्द करे"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Annulla"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "キャンセル"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "취소"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Annuleer"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cancelar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cancelar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Отменить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "İptal"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Скасувати"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "取消"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "取消"
}
}
}
},
"GEO-Iw-cKr.title" : {
"comment" : "Class = \"NSMenu\"; title = \"Format\"; ObjectID = \"GEO-Iw-cKr\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تنسيق"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formát"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Format"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Format"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formato"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Format"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "פורמט"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "प्रारूप"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formato"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "フォーマット"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "형식"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formaat"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formato"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formato"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Форматирование"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Biçim"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Форматування"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "格式"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "格式"
}
}
}
},
"gFA-SA-v9T.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"FSNotes Server\"; ObjectID = \"gFA-SA-v9T\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "خادم FSNotes"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes server"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes Server"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "FSNotes Server"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Servidor de FSNotes"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Serveur FSNotes"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes שרת"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes सर्वर"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Server FSNotes"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes サーバー"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes 서버"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes-server"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Servidor do FSNotes"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Servidor FSNotes"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сервер FSNotes"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes Sunucu"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes сервер"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes 服务器"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes 伺服器"
}
}
}
},
"Gg5-NO-KIQ.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"None Selected\"; ObjectID = \"Gg5-NO-KIQ\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "None Selected "
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nic nevybráno"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Keine ausgewählt"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "None Selected"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ninguno Seleccionado"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "None Selected "
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "None Selected "
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कोई भी नहीं चुना गया"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nessuno selezionato"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "選択なし"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "선택되지 않음"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Geen geselecteerd"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nada selecionado"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nenhum selecionado"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Не выбрано"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Seçilmedi"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Не вибрано"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "无选择"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "未選取"
}
}
}
},
"ghI-ln-bql.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Web:\"; ObjectID = \"ghI-ln-bql\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Web:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web:"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "वेब:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Веб:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Веб:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "主页:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web:"
}
}
}
},
"GhL-6I-558.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Header 4\"; ObjectID = \"GhL-6I-558\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "عنوان ٤"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nadpis 4"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Header 4"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Header 4"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Encabezado 4"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Titre 4"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "כותרת 4"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "हेडर 4"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Intestazione 4"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ヘッダー 4"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Header 4"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kop 4"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cabeçalho 4"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cabeçalho 4"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заголовок 4"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Başlık 4"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заголовок 4"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "4级标题"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "標題 4"
}
}
}
},
"goN-LO-L7l.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Reveal in Finder\"; ObjectID = \"goN-LO-L7l\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "فتح المجلد"
}
},
"cs" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Zobrazit ve Finderu"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordner anzeigen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Reveal in Finder"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar carpeta"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Localiser dans le Finder"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הצג ב-Finder"
}
},
"hi" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Finder में दिखाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostra nel Finder"
}
},
"ja" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Finderに表示"
}
},
"ko" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Finder에서 보기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Toon in Finder"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Mostrar no Finder"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Mostrar no Finder"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показать в Finder"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Finder'da göster"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показати у Finder"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "在访达中显示"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "顯示於 Finder"
}
}
}
},
"gra-E2-dYh.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Show in Finder\"; ObjectID = \"gra-E2-dYh\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "فتح المجلد"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zobrazit ve Finderu"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordner anzeigen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Show in Finder"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar carpeta"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Localiser dans le Finder"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הצג ב-Finder"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "Finder में दिखाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostra nel Finder"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Finderに表示"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Finder에서 보기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Toon in Finder"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar no Finder"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar no Finder"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показать в Finder"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Finder'da göster"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показати в Finder"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "在访达中显示"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "顯示於 Finder"
}
}
}
},
"GrP-W1-7ZQ.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Lock All Encrypted\"; ObjectID = \"GrP-W1-7ZQ\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "قفل جميع المشفرة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zamknout všechny šifrované"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Alle verschlüsselte sperren"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Lock All Encrypted"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloquear todas las notas encriptadas"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tout verrouiller"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "נעל פתקים מוצפנים"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "सभी एन्क्रिप्टेड लॉक करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Blocca tutte le note criptate"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ロックされたノートをすべて閉じる"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "모든 암호 노트 잠금"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vergrendel alle versleutelde"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloquear todos os criptografados"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloquear Todos os Criptografados"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заблокировать все секретные"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tüm Şifrelenmişleri Kilitle"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заблокувати всі секретні"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "锁定所有加密的笔记"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "鎖定所有加密項目"
}
}
}
},
"gVA-U4-sdL.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Paste\"; ObjectID = \"gVA-U4-sdL\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "لصق"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vložit"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Einfügen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Paste"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pegar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Coller"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הדבק"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पेस्ट"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Incolla"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ペースト"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "붙여넣기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Plakken"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Colar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Colar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вставить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yapıştır"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вставити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "粘贴"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "貼上"
}
}
}
},
"gWb-su-EdI.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"FSNotes\"; ObjectID = \"gWb-su-EdI\"; Note = \"#bc-ignore!\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "FSNotes"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
}
}
},
"Gwp-vX-YaR.headerCell.title" : {
"comment" : "Class = \"NSTableColumn\"; headerCell.title = \"Library\"; ObjectID = \"Gwp-vX-YaR\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "المكتبة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Knihovna"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Library"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Library"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Librería"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bibliothèque"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Library"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पुस्तकालय"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Libreria"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ライブラリ"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "라이브러리"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bibliotheek"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Biblioteca"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Biblioteca"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Библиотека"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kütüphane"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Бібліотека"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "资源库"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "資料庫"
}
}
}
},
"gY8-zt-Iak.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Dark\"; ObjectID = \"gY8-zt-Iak\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "داكن"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tmavý"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dunkel"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Dark"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Oscuro"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sombre"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "חשוך"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dark"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Scuro"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ダーク"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "다크"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Donker"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Escuro"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Escuro"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Тёмная"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Karanlık"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Темна"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "深色"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "深色"
}
}
}
},
"gYQ-MC-Xwt.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Zoom Out\"; ObjectID = \"gYQ-MC-Xwt\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تصغير"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zmenšit"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verkleinern"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Zoom Out"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Alejar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dézoomer"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "להקטין את התצוגה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "ज़ूम आउट"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ingrandimento"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ズームアウト"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "축소"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Uitzoomen"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Reduzir"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Reduzir"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Уменьшить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Uzaklaştır"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Зменшити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "缩小"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "縮小"
}
}
}
},
"H8h-7b-M4v.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"View\"; ObjectID = \"H8h-7b-M4v\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "عرض"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zobrazení"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Darstellung"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "View"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Visualización"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Affichage"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "תצוגה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "देखें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vista"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "表示"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "보기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Weergave"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Visualização"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vista"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вид"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Görünüm"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вигляд"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "视图"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "檢視"
}
}
}
},
"Hdn-bm-lbP.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Reset Settings\"; ObjectID = \"Hdn-bm-lbP\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "اعادة الضبط"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Resetovat nastavení"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Einstellungen zurücksetzen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Reset Settings"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Restablecer la configuración"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Réinitialiser les paramètres"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "אפס הגדרות"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "प्राथमिकताएं रीसेट करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ripristino delle impostazioni"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "設定のリセット"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "설정 초기화"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Instellingen resetten"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Redefinir configurações"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Repor definições"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сбросить настройки"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ayarları sıfırla"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Скинути налаштування"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "重置设置"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "重設設定"
}
}
}
},
"HFo-cy-zxI.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Show Spelling and Grammar\"; ObjectID = \"HFo-cy-zxI\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "عرض التدقيق الإملائي والنحوي"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zobrazit pravopis a gramatiku"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rechtschreibung und Grammatik einblenden"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Show Spelling and Grammar"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar ortografía y gramática"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Afficher Orthographe et grammaire"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הצג איות ודקדוק"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "वर्तनी और व्याकरण दिखाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostra Ortografia e Grammatica"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "スペルと文法を表示"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "맞춤법 및 문법 보기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Toon Spelling en Grammatica"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar Ortografia e Gramática"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar Ortografia e Gramática"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показать орфографию и грамматику"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yazım ve Dilbilgisini Göster"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показати правопис та граматику"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "显示拼写和语法"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "顯示拼字與文法"
}
}
}
},
"HFQ-gK-NFA.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Text Replacement\"; ObjectID = \"HFQ-gK-NFA\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "استبدال النص"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nahrazovat text"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Text ersetzen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Text Replacement"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Reemplazar texto"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remplacement de texte"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "מלל חלופי"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पाठ प्रतिस्थापन"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sostituzione Testo"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ユーザー辞書"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "텍스트 대치"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tekstvervanging"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Substituição de texto"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Substituição de Texto"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Замена текста"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Metin Değiştirme"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заміна тексту"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "文本替换"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "文字替代"
}
}
}
},
"HK7-Qq-ilB.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \".markdown\"; ObjectID = \"HK7-Qq-ilB\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : ".markdown"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : ".markdown"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : ".markdown"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : ".markdown"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : ".markdown"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : ".markdown"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : ".markdown"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : ".markdown"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : ".markdown"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : ".markdown"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : ".markdown"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : ".markdown"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : ".markdown"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : ".markdown"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : ".markdown"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : ".markdown"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : ".markdown"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : ".markdown"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : ".markdown"
}
}
}
},
"HmK-lp-ASv.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Open Note in New Window\"; ObjectID = \"HmK-lp-ASv\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "افتح في نافذة جديدة"
}
},
"cs" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Otevřít v novém okně"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "In neuem Fenster öffnen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Open Note in New Window"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Abrir en Nueva ventana"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ouvrir dans une nouvelle fenêtre"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "פתח בחלון חדש"
}
},
"hi" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "नई विंडो में खोलें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Apri in una nuova finestra"
}
},
"ja" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "新しいウィンドウで開きます"
}
},
"ko" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "새 창에서 열기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Notitie openen in nieuw venster"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Abrir em nova janela"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Abrir em nova janela"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Открыть в новом окне"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yeni Pencerede Aç"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Відкрити у новому вікні"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "在新窗口中打开"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "在新視窗開啟筆記"
}
}
}
},
"HPa-9J-5dS.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Reset\"; ObjectID = \"HPa-9J-5dS\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "إعادة ضبط"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Resetovat"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zurücksetzen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Reset"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Reiniciar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Réinitialiser"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "אִתחוּל"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "रीसेट करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ripristina"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "リセット"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "초기화"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Resetten"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Resetar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Redefinir"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сбросить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sıfırla"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Скинути"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "重置"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "重設"
}
}
}
},
"hPY-aY-QOE.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Search and Create\"; ObjectID = \"hPY-aY-QOE\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "بحث وانشاء"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hledat a vytvořit"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Suchen und ersetzen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Search and Create"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Buscar y crear"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rechercher et créer"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "חיפוש יצירה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "खोजें और बनाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cerca e crea"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "検索または新規作成"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "검색 및 추가"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zoek en creëer"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pesquisar e criar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pesquisar e criar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Найти и создать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ara ve oluştur"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Знайти або створити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "搜索或创建(按下回车即可创建)"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "搜尋並新增"
}
}
}
},
"hQb-2v-fYv.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Smart Quotes\"; ObjectID = \"hQb-2v-fYv\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "اقتباسات ذكية"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Inteligentní uvozovky"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Intelligente Anführungszeichen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Smart Quotes"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Comillas tipográficas"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Guillemets intelligents"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "מרכאות חכמות"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "स्मार्ट उद्धरण"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Virgolette Smart"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "スマート引用符"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "스마트 인용"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Slimme Aanhalingstekens"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aspas inteligentes"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aspas Inteligentes"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Смарт-кавычки"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Akıllı Alıntılar"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Розумні лапки"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "智能引号"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "智慧型引號"
}
}
}
},
"hqQ-4C-VJL.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"WikiLinks\"; ObjectID = \"hqQ-4C-VJL\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "ويكيلينكس"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "WikiLinks"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "WikiLinks"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "WikiLinks"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "WikiLinks"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "WikiLinks"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "WikiLinks"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "WikiLinks"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "WikiLinks"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "WikiLinks"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "위키 링크"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "WikiLinks"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "WikiLinks"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "WikiLinks"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Викиссылки"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Wiki Bağlantıları"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вікіпосилання"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "维基链接"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "維基連結"
}
}
}
},
"Hqu-Sx-xgo.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Move Up in the Notes List\"; ObjectID = \"Hqu-Sx-xgo\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تحرك لأعلى في قائمة الملاحظات"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Posunout nahoru v seznamu poznámek"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "In der Notizliste aufsteigen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Move Up in the Notes List"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mover arriba en la lista de notas"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Note précédente"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "עבור למעלה ברשימת הפתקים"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नोट्स सूची में ऊपर जाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Muovi in Alto nella Lista Note"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "上に移動"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "메모 목록에서 위로 이동"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Omhoog gaan in de notitielijst"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mover para cima lista de notas"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Subir na lista de Notas"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перейти вверх в списке заметок"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notlar Listesinde Yukarı Çık"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перейти вгору у списку нотаток"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "在笔记列表中上移"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "在筆記清單中上移"
}
}
}
},
"HyV-fh-RgO.title" : {
"comment" : "Class = \"NSMenu\"; title = \"View\"; ObjectID = \"HyV-fh-RgO\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "عرض"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zobrazení"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Darstellung"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "View"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Visualización"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Affichage"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "תצוגה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "देखें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vista"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "表示"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "보기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Weergave"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Visualização"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vista"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вид"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Görünüm"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вигляд"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "视图"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "檢視"
}
}
}
},
"hz2-CU-CR7.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Check Document Now\"; ObjectID = \"hz2-CU-CR7\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "فحص المستند الآن"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zkontrolovat dokument"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dokument jetzt prüfen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Check Document Now"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Comprobar documento ahora"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vérifier le document maintenant"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "בדוק את המסמך כעט"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "दस्तावेज़ अभी जांचें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Controlla ora il documento"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "今すぐドキュメントをチェック"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "지금 도큐멘트 검사"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Controleer Document Nu"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verificar documento agora"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verificar Documentos Agora"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Проверить документ"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Belgeyi Şimdi Kontrol Et"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перевіряти документ"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "立即检查文档"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "立即檢查文件"
}
}
}
},
"hz9-B4-Xy5.title" : {
"comment" : "Class = \"NSMenu\"; title = \"Services\"; ObjectID = \"hz9-B4-Xy5\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "الخدمات"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Služby"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Services"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Services"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Servicios"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Services"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "שירותים"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "सेवाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Servizi"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "サービス"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "서비스"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Services"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Serviços"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Serviços"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Услуги"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hizmetler"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сервіси"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "服务"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "服務"
}
}
}
},
"i2S-pt-KQH.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Trash:\"; ObjectID = \"i2S-pt-KQH\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "الملهملات"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Koš"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Papierkorb:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Trash:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Papelera:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Corbeille:"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "פח אשפה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कूडा:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cestino:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ゴミ箱:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "휴지통:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Prullenmand:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lixo"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lixo:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Корзина:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Çöp:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сміття:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "废弃:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "垃圾桶:"
}
}
}
},
"IHG-4U-pF1.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Inbox\"; ObjectID = \"IHG-4U-pF1\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "الوارد"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Příchozí"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Posteingang"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Inbox"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Entrada"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Boîte de réception"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "תיבת דואר נכנס"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "इनबॉक्स"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "In Entrata"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "未整理"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "받은 편지함"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Postvak In"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Caixa de entrada"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Caixa de entrada"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Входящие"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Gelen kutusu"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вхідні"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "收集箱"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "收件匣"
}
}
}
},
"iIP-wI-OaZ.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Commit & Push\"; ObjectID = \"iIP-wI-OaZ\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "تخزين النسخ الاحتياطي"
}
},
"cs" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Zálohovat nyní"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Commit & Push"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Commit & Push"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Almacenamiento de respaldo"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sauvegarder le stockage"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "גבה עכשיו"
}
},
"hi" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "अभी बैकअप लें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Salva archivio"
}
},
"ja" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "今すぐバックアップ"
}
},
"ko" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "저장소 백업"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Back-up opslag"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Fazer backup agora"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Cópia de segurança de armazenamento"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Создать резервную копию"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Commit & Push"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Commit & Push"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "Commit & Push"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "提交並推送"
}
}
}
},
"IlF-tS-GFG.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Lock on screen saver activated\"; ObjectID = \"IlF-tS-GFG\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "قفل عند تفعيل شاشة التوقف"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zamknout při spořiči obrazovky"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sperren, wenn der Bildschirmschoner aktiv"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Lock on screen saver activated"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloquear cuando se active el salvapantallas"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verrouiller à l'activation de l'économiseur d'écran"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "נעל בהפעלת שומר מסך"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "स्क्रीन सेवर सक्रिय होने पर लॉक करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Blocca a screen saver attivato"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "スクリーンセーバー起動時"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "화면 보호기 실행시 잠금"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vergrendel bij activering schermbeveiliging"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloquear quando o protetor de tela ativar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloquear quando o protector de ecrã activar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заблокировать при включении скринсейвера"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ekran koruyucusu etkinken kilitlendi"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Блокувати при активації скрінсейвера"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "系统激活屏幕保护后自动锁定"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "啟動螢幕保護程式時鎖定"
}
}
}
},
"iNK-dg-n5E.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"New Password:\"; ObjectID = \"iNK-dg-n5E\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "كلمة المرور الجديدة:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nové heslo:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Neue Passwort:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "New Password:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Contraseña nueva:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nouveau mot de passe :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "סיסמה חדשה:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नया पासवर्ड:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nuova password:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "新しいパスワード:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "새 비밀번호:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nieuw wachtwoord:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nova senha:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nova palavra-passe:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Новый пароль:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yeni şifre :"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Новий пароль:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "新的密码:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "新密碼:"
}
}
}
},
"ioc-u5-XRA.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Hint:\"; ObjectID = \"ioc-u5-XRA\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تلميحة :"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nápověda:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hint:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Hint:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Indicación:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pense-bête :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "רמז:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "संकेत:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Suggerimento:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ヒント:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "힌트:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hint:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dica:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dica:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Подсказка:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "İpucu:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Підказка:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "提示:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "提示:"
}
}
}
},
"IPu-Ll-IBE.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Shift Right\"; ObjectID = \"IPu-Ll-IBE\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تحول اليمين"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Posunout doprava"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Text nach rechts bewegen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Shift Right"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tabular a la derecha"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Décaler vers la droite"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הזחה ימינה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "दांयी ओर शिफ्ट करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sposta a destra"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "右にシフト"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "들여쓰기 추가"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verschuif Rechts"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mover para esquerda"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Deslocar à Direita"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сдвиг вправо"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sağa kaydır"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Зміщення вправо"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "右移"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "向右位移"
}
}
}
},
"iQ9-lm-lFb.placeholderString" : {
"comment" : "Class = \"NSTextFieldCell\"; placeholderString = \"no key\"; ObjectID = \"iQ9-lm-lFb\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "no key"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "bez klíče"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "no key"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "no key"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "no key"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "no key"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "no key"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कोई चाबी नहीं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "no key"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "no key"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "no key"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "no key"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "no key"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "no key"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "нет ключа"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "anahtar yok"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "no key"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "no key"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "無金鑰"
}
}
}
},
"IQv-IB-iLA.title" : {
"comment" : "Class = \"NSWindow\"; title = \"FSNotes\"; ObjectID = \"IQv-IB-iLA\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "FSNotes"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
}
}
},
"iUm-Zm-zeg.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Line Spacing:\"; ObjectID = \"iUm-Zm-zeg\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تباعد الاسطر"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rozestup řádků:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zeilenabstand:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Line Spacing:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Espaciado de línea:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Espacement des lignes :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "מרווח בין שורות:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पंक्ति रिक्ति:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Interlinea:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "行間隔:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "줄 간격:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Regelafstand:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Espaçamento da linha:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Espaçamento de linhas:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Межстрочный интервал:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Satır Aralığı:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Міжрядковий інтервал:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "行间距:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "行距:"
}
}
}
},
"IWL-lp-G1M.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Format: Untitled Note\"; ObjectID = \"IWL-lp-G1M\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "التنسيق: Untitled Note"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formát: Poznámka bez názvu"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Format: Untitled Note"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Format: Untitled Note"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formato: Nota sin título"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Format: Untitled Note"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "פורמט: Untitled Note"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "प्रारूप: शीर्षक रहित नोट"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formato: Nota senza titolo"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "フォーマット: 名称未設定"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "체재: Untitled Note"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Format: Untitled Note"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formato: nota sem título"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formato: Nota sem título"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Формат: Untitled Note"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Biçim: Başlıksız Not"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Формат: Нотатка без назви"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "格式: 无标题笔记"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "格式:無標題筆記"
}
}
}
},
"Izt-6v-pKO.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Line Width:\"; ObjectID = \"Izt-6v-pKO\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "عرض الخط:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Šířka textu:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Linienbreite:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Line Width:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ancho de línea:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Largeur de ligne :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "רוחב שורות:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पंक्ति चौडाई:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Larghezza linea:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "行幅:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "줄 간격:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lijnbreedte:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Largura da linha"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Largura da linha:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ширина строки:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Çizgi Genişliği:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ширина рядка:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "行宽:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "行寬:"
}
}
}
},
"jFN-Dp-LON.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Pin/Unpin\"; ObjectID = \"jFN-Dp-LON\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "دبوس / إلغاء التثبيت"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Připnout/odepnout"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fixieren/Loslösen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Pin/Unpin"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Anclar/Desanclar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Épingler/Désépingler"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הצמד/בטל הצמדה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पिन/अनपिन"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fissa/sblocca"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ピンで固定/ピン固定を解除"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "고정/고정 해제"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pin/VerwijderPin"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fixar/Desafixar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fixar/soltar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Прикрепить/открепить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sabitle/Sabitlemeyi kaldır"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Закріпити/відкріпити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "置顶/取消置顶"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "釘選/取消釘選"
}
}
}
},
"jLq-8F-n0X.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Rename\"; ObjectID = \"jLq-8F-n0X\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "اعادة تسمية"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Přejmenovat"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Umbenennen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Rename"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renombrar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renommer"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "שנה שם"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नाम बदलें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rinomina"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "名称変更"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "이름 변경"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hernoem"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renomear"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renomear"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Переименовать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yeniden isimlendir"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перейменувати"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "重命名"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "重新命名"
}
}
}
},
"jQ1-6K-9ar.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"🔗fsnotes/contributors\"; ObjectID = \"jQ1-6K-9ar\"; Note = \"#bc-ignore!\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "🔗fsnotes/contributors"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "🔗fsnotes/contributors"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "🔗fsnotes/contributors"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "🔗fsnotes/contributors"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "🔗fsnotes/contributors"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "🔗fsnotes/contributors"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "🔗fsnotes/contributors"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "🔗fsnotes/contributors"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "🔗fsnotes/contributors"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "🔗fsnotes/contributors"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "🔗fsnotes/contributors"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "🔗fsnotes/contributors"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "🔗fsnotes/contributors"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "🔗fsnotes/contributors"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "🔗fsnotes/contributors"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "🔗fsnotes/katkıda bulunanlar"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "🔗fsnotes/contributors"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "🔗fsnotes/contributors"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "🔗fsnotes/contributors"
}
}
}
},
"jrj-ea-xmm.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Visibility:\"; ObjectID = \"jrj-ea-xmm\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "الرؤية:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Viditelnost:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sichtbarkeit:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Visibility:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Visibilidad:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Visibilité :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "ראות:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "दृश्यता:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Visibilità:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "視認性:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "가시성:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zichtbaarheid:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Visibilidade:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Visibilidade:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Видимость:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Görünürlük:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Видимість:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "可见性:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "能見度:"
}
}
}
},
"jRm-BN-BNK.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Header 1\"; ObjectID = \"jRm-BN-BNK\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "عنوان ١"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nadpis 1"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Header 1"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Header 1"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Encabezado 1"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Titre 1"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "כותרת 1"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "हेडर 1"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Intestazione 1"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ヘッダー 1"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Header 1"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kop 1"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cabeçalho 1"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cabeçalho 1"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заголовок 1"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Başlık 1"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заголовок 1"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "1级标题"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "標題 1"
}
}
}
},
"jRr-Ih-RYc.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"**\"; ObjectID = \"jRr-Ih-RYc\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "**"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "**"
}
}
},
"shouldTranslate" : false
},
"juB-By-EsE.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Set\"; ObjectID = \"juB-By-EsE\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تعيين"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nastavit"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Satz"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Set"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Establecer"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Régler"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "מַעֲרֶכֶת"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "सेट करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Impostare"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Set"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "세트"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Set"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Definir"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Definir"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Выбрать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ayarla"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вибрати"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "设置"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "設定"
}
}
}
},
"jxT-CU-nIS.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Format\"; ObjectID = \"jxT-CU-nIS\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تنسيق"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formát"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Format"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Format"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formato"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Format"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "פורמט"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "प्रारूप"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formato"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "フォーマット"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "형식"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formaat"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formato"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formato:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Форматирование"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Biçim"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Форматування"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "格式"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "格式"
}
}
}
},
"K4N-le-FPU.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Delete Web Page\"; ObjectID = \"K4N-le-FPU\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "حذف صفحة الويب"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Smazat webovou stránku"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Geteilte löschen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Delete Web Page"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Eliminar página web"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Supprimer la page Web"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "מחק דף אינטרנט"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "वेब पेज हटाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Elimina pagina web"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Delete Web Page"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "웹 페이지 삭제"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Webpagina verwijderen"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Deletar página Web"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Excluir página da Web"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Удалить веб-страницу"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web sayfasını Sil"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Видалити веб-сторінку"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "删除网页"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "刪除網頁"
}
}
}
},
"k32-YP-yyI.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Italic\"; ObjectID = \"k32-YP-yyI\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "مائل"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kurzíva"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kursiv"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Italic"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cursiva"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Italique"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "נטוי"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "तिरछा"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Italic"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "イタリック"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "이텔릭체"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cursief"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Itálico"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Itálico"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Курсив"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "İtalik"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Курсив"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "斜体"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "斜體"
}
}
}
},
"KaC-Mz-siK.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Password:\"; ObjectID = \"KaC-Mz-siK\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "كلمة المرور:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Heslo:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Passwort:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Password:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Contraseña:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mot de p. :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "סיסמה:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पासवर्ड:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Parola d'ordine:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "パスワード:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "암호:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Wachtwoord:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Senha:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Passe:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Пароль:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Şifre:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Пароль:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "密码:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "密碼:"
}
}
}
},
"kbK-Um-cQk.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Use first line as title\"; ObjectID = \"kbK-Um-cQk\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "استخدم اول سطر كعنوان"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Použít první řádek jako nadpis"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Erste Zeile als Titel verwenden"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Use first line as title"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Utilizar la primera línea como título"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Utiliser la première ligne comme titre"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "השתמש בשורה הראשונה ככותרת"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "प्रथम पंक्ति को शीर्षक के रूप में उपयोग करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Usa la prima riga come titolo"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "最初の行をタイトルとして使用"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "첫 줄을 제목으로 사용"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Gebruik eerste regel als titel"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Usar primeira linha como título"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Utilizar a primeira linha como título"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Первая строка как заголовок"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "İlk satırı başlık olarak kullanın"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перший рядок як заголовок"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "将内容第一行提取为标题"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "使用第一行作為標題"
}
}
}
},
"Kd2-mp-pUS.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Show All\"; ObjectID = \"Kd2-mp-pUS\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "عرض الكل"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zobrazit vše"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Alle anzeigen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Show All"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar todo"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tout afficher"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הצג הכל"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "सब दिखाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostra Tutto"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "すべてを表示"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "모두 보기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Toon alle"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar todos"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar Todos"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показать все"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hepsini göster"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показати все"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "显示全部"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "顯示全部"
}
}
}
},
"kg2-3u-V99.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Lock/Unlock\"; ObjectID = \"kg2-3u-V99\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "فقل/فتح الفقل"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zamknout/odemknout"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sperren/Entsperren"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Lock/Unlock"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloquear/desbloquear"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verrouiller/Déverrouiller"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "נעל/פתח"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "लॉक/अनलॉक"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Blocca/sblocca"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ロック/ロックの削除"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "잠금/잠금 해제"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vergrendel/ontgrendel"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloquear/desbloquear"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloquear/desbloquear"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заблокировать/разблокировать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kilitle/Kilidi Aç"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заблокувати/розблокувати"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "锁定/解锁"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "鎖定/解鎖"
}
}
}
},
"kIy-TN-XMS.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Close\"; ObjectID = \"kIy-TN-XMS\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "اغلاق"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zavřít"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Schließen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Close"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cerrar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fermer"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "סגור"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "बंद करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Chiudi"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "閉じる"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "닫기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sluit"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fechar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fechar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Закрыть"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kapat"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Закрити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "关闭"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "關閉"
}
}
}
},
"KIz-OO-IQT.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Preview MathJax\"; ObjectID = \"KIz-OO-IQT\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "معاينة MathJax "
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Náhled MathJax"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vorschau MathJax"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Preview MathJax"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Previsualizar MathJax"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aperçu MathJax"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "תצוגת MathJax"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पूर्वावलोकन MathJax"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Anteprima MathJax"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "MathJaxをプレビュー"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "미리보기 MathJax"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Voorvertoning MathJax"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pré-visualização do MathJax"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pré-visualizar MathJax"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Предпросмотр MathJax"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "MathJaxı Önizleyin"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Попередній перегляд MathJax"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "预览 MathJax"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "預覽 MathJax"
}
}
}
},
"kqJ-Fr-EeB.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"1\"; ObjectID = \"kqJ-Fr-EeB\"; Note = \"#bc-ignore!\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "1"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "1"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "1"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "1"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "1"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "1"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "1"
}
}
}
},
"KST-y3-KvM.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Allow Touch ID to unlock notes\"; ObjectID = \"KST-y3-KvM\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "السماح لبصمة الاصبع لفتح الملاحظات"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Povolit Touch ID pro odemykání poznámek"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "TouchID erlauben zum Entsperren von Notizen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Allow Touch ID to unlock notes"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Permitir desbloquar las notas con Touch ID"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Déverrouillage de notes par Touch ID"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "אפשר ל-Touch ID לפתוח פתקים"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "टच आईडी को नोट्स अनलॉक करने की अनुमति दें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Consenti a Touch ID di sbloccare le note"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Touch IDを使ってロックされたノートを表示"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Touch ID를 이용하여 노트 잠금 해제"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sta Touch ID toe om notities te ontgrendelen"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Permitir Touch ID para bloquear notas"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Permitir desbloquear notas com Touch ID"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Разблокировка Touch ID"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notların kilidini açmak için Touch ID'ye izin verin"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Використовувати Touch ID "
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "允许使用 Touch ID 解锁笔记"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "允許使用 Touch ID 解鎖筆記"
}
}
}
},
"L20-FT-VZz.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Origin for main project:\"; ObjectID = \"L20-FT-VZz\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Origin للمشروع الرئيسي:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Origin pro hlavní projekt:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Origin for main project:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Origin for main project:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Origin para el proyecto principal:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Origin pour le projet principal:"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Origin לפרויקט הראשי:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "मुख्य प्रोजैक्ट का उद्गम स्थान:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Origin per il progetto principale:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Origin メインプロジェクト用:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Origin 메인 프로젝트를 위해:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Origin voor hoofdproject::"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Origem do projeto principal:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Origin para projeto principal:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Удаленный репозиторий (origin):"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ana projenin kökeni:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remote origin основного проекту:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "Origin 主要项目:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "主要專案來源:"
}
}
}
},
"ldu-U8-PD1.title" : {
"comment" : "Class = \"NSWindow\"; title = \"Preferences\"; ObjectID = \"ldu-U8-PD1\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "التفضيلات"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Předvolby"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Einstellungen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Preferences"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Preferencias"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Préférences"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "העדפות"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "प्राथमिकताएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Preferenze"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "環境設定…"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "환경설정"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Voorkeuren"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Preferências"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Preferências"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Окно"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tercihler"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вікно"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "偏好设置"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "偏好設定"
}
}
}
},
"LFw-De-3DP.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Actual Size\"; ObjectID = \"LFw-De-3DP\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "الحجم الأصلي"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Skutečná velikost"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tatsächliche Größe"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Actual Size"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tamaño real"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Taille réelle"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "גודל אמיתי"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "वास्तविक आकार"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dimensione reale"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "実寸"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "실제 크기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Werkelijke grootte"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tamanho real"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tamanho real"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Фактический размер"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Gerçek Boyut"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Фактичний розмір"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "实际尺寸"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "實際大小"
}
}
}
},
"lhy-wX-Q4T.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Reset:\"; ObjectID = \"lhy-wX-Q4T\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "إعادة ضبط:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Resetovat:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zurücksetzen:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Reset:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Restablecer:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Réinitialiser :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "אִתחוּל:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "रीसेट करें:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Azzeramento:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "リセット"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "초기화"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Reset:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Redefinir:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Repor:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сброс:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sıfırla:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Скинути:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "重置"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "重設:"
}
}
}
},
"LKs-o1-uhL.title" : {
"comment" : "Class = \"NSMenu\"; title = \"Share\"; ObjectID = \"LKs-o1-uhL\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Teilen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Share"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Compartir"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Partager"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "साझा करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Condividi"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Поделиться"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Paylaş"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Поділитися"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "分享"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "分享"
}
}
}
},
"Lmy-lE-9MZ.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Header 3\"; ObjectID = \"Lmy-lE-9MZ\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "عنوان ٣"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nadpis 3"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Header 3"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Header 3"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Encabezado 3"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Titre 3"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "כותרת 3"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "हेडर 3"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Intestazione 3"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ヘッダー 3"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Header 3"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kop 3"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cabeçalho 3"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cabeçalho 3"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заголовок 3"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Başlık 3"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заголовок 3"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "3级标题"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "標題 3"
}
}
}
},
"LPT-uW-BtF.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Title\"; ObjectID = \"LPT-uW-BtF\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "عنوان"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nadpis"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Title"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Title"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Título"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Titre"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "כותרת"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "शीर्षक"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Titolo"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "タイトル"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "제목"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Titel"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Título"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Título"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заголовок"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Başlık"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заголовок"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "标题"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "標題"
}
}
}
},
"ltm-qj-nke.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Images Width:\"; ObjectID = \"ltm-qj-nke\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "عرض الصور:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Šířka obrázků:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bilder Breite:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Images Width:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ancho de imágenes:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Largeur des images :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "רוחב תמונות:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "छवियाँ चौड़ाई:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Larghezza delle immagini:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "画像の幅:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "이미지 가로폭:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Afbeeldingen breedte:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Largura das imagens:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Largura de imagens:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ширина изображений:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Resim Genişliği:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ширина зображення:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "图像宽度:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "圖片寬度:"
}
}
}
},
"LTw-w4-tEo.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Bold\"; ObjectID = \"LTw-w4-tEo\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "سميك"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tučné"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fett"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Bold"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Negrita"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Gras"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "עבה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "बोल्ड"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Grassetto"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ボールド"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "볼드"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vet"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Negrito"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Realçado"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Жирный"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kalın"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Жирний"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "粗体"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "粗體"
}
}
}
},
"LZ2-uY-6YK.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Private key\"; ObjectID = \"LZ2-uY-6YK\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Private key"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Soukromý klíč"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Private key"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Private key"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Private key"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Private key"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Private key"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "निजी कुंजी"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Private key"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Private key"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Private key"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Private key"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Chave privada"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Private key"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Закрытый ключ"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Özel anahtar"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Private key"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "Private key"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "私密金鑰"
}
}
}
},
"M29-fW-FJa.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Hide FSNotes when activating another application\"; ObjectID = \"M29-fW-FJa\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "إخفاء FSNotes عند تفعيل تطبيق آخر"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Skrýt FSNotes při aktivaci jiné aplikace"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes ausblenden, wenn andere Anwendung aktiv"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Hide FSNotes when activating another application"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ocultar FSNotes cuando no sea la aplicación activa"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Masquer FSNotes à l'activation d'une autre app"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הסתר את FSNotes כשמפעילים אפליקציה אחרת"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "किसी अन्य एप्लिकेशन को सक्रिय करते समय FSNotes छिपाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nascondi FSNotes quando usi altre app"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "他のアプリケーションがアクティブ時にFSNotesを非表示にする"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "다른 애플리케이션 활성화 시 FSNotes 숨기기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verberg FSNotes bij het activeren van een andere applicatie"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ocultar o FSNotes ao ativar outro aplicativo"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ocultar FSNotes quando há outra aplicação activa"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Прятать окно если активно другое приложение"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Başka bir uygulamayı etkinleştirirken FSNotes'u gizle"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сховати при активуванні іншої программи"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "激活其他应用时自动隐藏 FSNotes"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "啟動其他應用程式時隱藏 FSNotes"
}
}
}
},
"MCR-1v-3Wc.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"TextBundle\"; ObjectID = \"MCR-1v-3Wc\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "حزمة النص"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "TextBundle"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "TextBundle"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "TextBundle"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "TextBundle"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "TextBundle"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "TextBundle"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "TextBundle"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "TextBundle"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "TextBundle"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "텍스트 번들"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "TextBundle"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "TextBundle"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "TextBundle"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "TextBundle"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "MetinPaketi"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "TextBundle"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "TextBundle"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "TextBundle"
}
}
}
},
"ME1-My-h4q.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"atom-one\"; ObjectID = \"ME1-My-h4q\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "atom-one"
}
},
"ja" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Atom One Light"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "atom-one"
}
}
},
"shouldTranslate" : false
},
"mK0-16-Mxo.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"4 Spaces\"; ObjectID = \"mK0-16-Mxo\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "4 Spaces"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "4 mezery"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "4 Spaces"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "4 Spaces"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "4 Spaces"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "4 Spaces"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "4 Spaces"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "4 स्थान"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "4 Spaces"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "4 スペース"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "4 Spaces"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "4 Spaces"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "4 espaços"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "4 Spaces"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "4 пробела"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "4 Boşluk"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "4 пробіли"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "缩进 4 个空格"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "4 個空格"
}
}
}
},
"mK6-2p-4JG.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Check Grammar With Spelling\"; ObjectID = \"mK6-2p-4JG\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تحقق من القواعد مع التدقيق الإملائي\n"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kontrolovat gramatiku a pravopis"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Grammatik und Rechtschreibung prüfen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Check Grammar With Spelling"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Comprobar gramática con la ortografía"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vérifier la grammaire avec l'orthographe"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "בדוק דקדוק ביחד עם איות"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "वर्तनी के साथ व्याकरण की जाँच करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Controlla Ortografia e Grammatica"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "スペルと一緒に文法をチェック"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "맞춤법 및 문법 검사"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Controleer grammatica tegelijk met spelling"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verificar Ortografia e Gramática"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verificar gramática com ortografia"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Проверить грамматику с орфографией"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yazımla Dilbilgisini Kontrol Et"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перевіряти граматику та правопис"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "检查拼写和语法"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "檢查拼字與文法"
}
}
}
},
"MlK-p2-CxF.title" : {
"comment" : "Class = \"NSMenu\"; title = \"Window\"; ObjectID = \"MlK-p2-CxF\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "نافذة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Okno"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fenster"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Window"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ventana"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fenêtre"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "חלון"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "विंडो"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Finestra"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ウィンドウ"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "윈도우"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Venster"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Janela"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Janela"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Окно"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pencere"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вікно"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "窗口"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "視窗"
}
}
}
},
"mr6-e8-9hL.placeholderString" : {
"comment" : "Class = \"NSTextFieldCell\"; placeholderString = \"https://example.com/\"; ObjectID = \"mr6-e8-9hL\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "https://example.com/"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "https://priklad.com/"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "https://example.com/"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "https://example.com/"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "https://example.com/"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "https://example.com/"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "https://example.com/"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "https://example.com/"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "https://example.com/"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "https://example.com/"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "https://example.com/"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "https://example.com/"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "https://example.com/"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "https://example.com/"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "https://example.com/"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "https://domainadi.com/"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "https://example.com/"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "https://example.com/"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "https://example.com/"
}
}
}
},
"mvt-gI-iG0.title" : {
"comment" : "Class = \"NSViewController\"; title = \"Advanced\"; ObjectID = \"mvt-gI-iG0\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "متقدمة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pokročilé"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Erweitert"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Advanced"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Avanzado"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Avancé"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "מתקדם"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "उन्नत"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Avanzate"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "詳細"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "고급"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Geavanceerd"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Avançado"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Avançado"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Расширенные"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Gelişmiş"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Розширені"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "高级"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "進階"
}
}
}
},
"mXw-d9-js5.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Container:\"; ObjectID = \"mXw-d9-js5\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "الحاوية:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kontejner:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Container:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Container:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Contenedor:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Conteneur :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "מיכל:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कंटेनर:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Container:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "コンテナ:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "컨테이너:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Container:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Container:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Contentor:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Контейнер:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Konteyner:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Контейнер:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "容器:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "容器:"
}
}
}
},
"n0M-SN-fzg.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Toggle Todo\"; ObjectID = \"n0M-SN-fzg\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تبديل Todo"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Přepnout úkol"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Auf Todo umschalten"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Toggle Todo"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Insertar Pendiente"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cocher la tâche"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "החלף מצב מטלה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "टॉगल टूडू"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Passa a Da Fare"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "タスクの切り替え"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "할 일 토글"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Wissel Te Doen"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Alterar 'A fazer'"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Alternar tarefa"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Переключить Todo"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Geçiş Yap"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Завдання"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "切换待办事项"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "切換待辦事項狀態"
}
}
}
},
"N8h-ep-HFG.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Clickable links\"; ObjectID = \"N8h-ep-HFG\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clickable links"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Klikatelné odkazy"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clickable links"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Clickable links"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clickable links"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Liens cliquables"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "קישורים ללחיצה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "क्लिक करने योग्य लिंक"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clickable links"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "クリック可能なリンク"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clickable links"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clickable links"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Links clicáveis"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clickable links"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Кликабельные ссылки"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tıklanabilir bağlantılar"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Клікабельні посилання"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "可点击的链接"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "可點擊連結"
}
}
}
},
"nBn-aV-7mt.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Change\"; ObjectID = \"nBn-aV-7mt\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تغيير"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Změnit"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bearbeiten"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Change"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cambiar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Changer"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "שנה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "बदलें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cambia"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "変更"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "변경"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verander"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Alterar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Alterar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Изменить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Değiştir"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Змінити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "更改"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "變更"
}
}
}
},
"NcS-0N-6uU.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Passphrase:\"; ObjectID = \"NcS-0N-6uU\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "عبارة المرور:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Přístupová fráze:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Passphrase:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Passphrase:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Frase de contraseña:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Passphrase:"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "ביטוי סיסמה:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पासफ्रेज:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Frase d'accesso:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "パスフレーズ:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "암호:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Wachtwoordzin:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Frase secreta:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Senha:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Парольная фраза:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Parola:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Парольна фраза:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "密码:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "通關密語:"
}
}
}
},
"Ncv-c4-Dmg.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Tab\"; ObjectID = \"Ncv-c4-Dmg\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tab"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tabulátor"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tab"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Tab"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tab"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tab"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tab"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "टैब"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tab"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "タブ"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tab"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tab"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tab"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tab"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Таб"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sekme"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Таб"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tab"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "分頁"
}
}
}
},
"nCW-CZ-qC7.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Print\"; ObjectID = \"nCW-CZ-qC7\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "طباعة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tisknout"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Drucken"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Print"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Imprimir"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Imprimer"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הדפס"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "प्रिंट"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Stampa"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "印刷"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "프린트"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Druk af"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Imprimir"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Imprimir"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Печать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yazdır"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Роздрукувати"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "打印"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "列印"
}
}
}
},
"Ng2-HH-bmY.label" : {
"comment" : "Class = \"NSTabViewItem\"; label = \"Web\"; ObjectID = \"Ng2-HH-bmY\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Web"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "वेब"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "편물"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Веб"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Веб"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "生成网页"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "網頁"
}
}
}
},
"NHv-lG-vxt.title" : {
"comment" : "Class = \"NSViewController\"; title = \"General\"; ObjectID = \"NHv-lG-vxt\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "عام"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Obecné"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "General"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "General"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "General"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Général"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "כללי"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "सामान्य"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Generali"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "一般"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "일반"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Algemeen"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Geral"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Geral"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Главные"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Genel"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Головні"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "常规"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "一般"
}
}
}
},
"NMo-om-nkz.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Services\"; ObjectID = \"NMo-om-nkz\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "الخدمات"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Služby"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Services"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Services"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Servicios"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Services"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "שירותים"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "सेवाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Servizi"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "サービス"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "서비스"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Services"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Serviços"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Serviços"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сервисы"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hizmetler"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сервіси"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "服务"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "服務"
}
}
}
},
"nTf-oq-7k2.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Use TextBundle info.json to store c/mtime\"; ObjectID = \"nTf-oq-7k2\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "استخدام TextBundle Info.json لتخزين c/متى"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Použití TextBundle info.json pro uložení c/mtime"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "TextBundle info.json zum Speichern von c/mtime verwenden"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Use TextBundle info.json to store c/mtime"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Utilizar TextBundle info.json para almacenar c/mtime"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Utiliser le TextBundle info.json pour stocker le c/mtime"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "השתמש בקובץ info.json של TextBundle כדי לאחסן c/mtime"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "c/mtime संग्रहीत करने के लिए TextBundle info.json का उपयोग करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Usare TextBundle info.json per memorizzare c/mtime"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "c/mtimeを格納するためにTextBundle info.jsonを使用する。"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "텍스트 번들 info.json을 사용하여 c/mtime을 저장합니다."
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Gebruik TextBundle info.json om c/mtime op te slaan"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Use TextBundle info.json para armazenar c/mtime"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Utilizar TextBundle info.json para armazenar c/mtime"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Использовать TextBundle info.json для хранения c/mtime"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hizmetler"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Використовувати TextBundle info.json для зберігання c/mtime"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "使用 TextBundle info.json 存储 c/mtime"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "使用 TextBundle info.json 儲存建立/修改時間"
}
}
}
},
"Nw2-km-iDW.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Touch ID:\"; ObjectID = \"Nw2-km-iDW\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "بصمة الاصبع:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Touch ID:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Touch ID:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Touch ID:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Touch ID:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Touch ID :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Touch ID:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "टच आईडी:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Touch ID:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Touch ID:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Touch ID:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vingerafdruk ID:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Touch ID"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Touch ID:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Touch ID:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dokunmatik Kimlik:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Touch ID:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "Touch ID:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "Touch ID:"
}
}
}
},
"NZK-ki-p6Z.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Zoom In\"; ObjectID = \"NZK-ki-p6Z\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تكبير"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zvětšit"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Einzoomen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Zoom In"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Acercar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Agrandir"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "לְהִתְמַקֵד"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "ज़ूम इन"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ingrandisci"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "拡大表示"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "줌인"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Inzoomen"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aumentar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ampliar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Увеличить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yakınlaştır"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Збільшити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "放大"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "放大"
}
}
}
},
"o2f-1e-Dvp.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Reset\"; ObjectID = \"o2f-1e-Dvp\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Reset"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Resetovat"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Reset"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Reset"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Reset"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Reset"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Reset"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "रीसेट करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Reset"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Reset"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Reset"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Reset"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Resetar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Reset"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сбросить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sıfırla"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Reset"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "Reset"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "重設"
}
}
}
},
"o6a-px-wp7.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Show in Terminal\"; ObjectID = \"o6a-px-wp7\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "اظهار فيTerminal"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zobrazit v Terminálu"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zeigen in Terminal"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Show in Terminal"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar en la terminal"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Afficher dans le Terminal"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הצג במסוף"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "टर्मिनल में दिखाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostra nel Terminale"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ターミナルで開く"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "터미널에서 보기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Toon in Terminal"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar no Terminal"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar no Terminal"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показать в терминале"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Terminalde göster"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показати в терміналі"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "在终端中显示"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "在終端機中顯示"
}
}
}
},
"O8Z-cg-XnH.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Import\"; ObjectID = \"O8Z-cg-XnH\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "استيراد"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Importovat"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Importieren"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Import"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Importar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Importer"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "ייבא"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "आयात"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Importa"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "取り込む..."
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "가져오기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Importeren"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Importar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Importar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Импортировать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "İçe aktar"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Імпортувати"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "导入"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "匯入"
}
}
}
},
"O9f-Lf-HF6.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Show in Sidebar\"; ObjectID = \"O9f-Lf-HF6\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "إظهار في الشريط الجانبي"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zobrazit v bočním panelu"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "In der Seitenleiste anzeigen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Show in Sidebar"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar en la barra lateral"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Afficher dans la barre latérale"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הצג בסרגל צד"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "साइडबार में दिखाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostra nella barra laterale"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "サイドバーに表示"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "사이드 바에 표시"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Toon in zijbalk"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar no menu lateral"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar na barra lateral"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показывать в сайдбаре"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kenar Çubuğunda Göster"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показувати на бічній панелі"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "在侧边栏中显示"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "顯示於側邊欄"
}
}
}
},
"O9K-a1-3eu.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Title\"; ObjectID = \"O9K-a1-3eu\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "العنوان"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nadpis"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Title"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Title"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Título"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Titre"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "כותרת"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "शीर्षक"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Titolo"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "タイトル"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "제목"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Titel"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Título"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Título"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заголовок"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Başlık"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заголовок"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "标题"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "標題"
}
}
}
},
"oeL-rE-fXz.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"5\"; ObjectID = \"oeL-rE-fXz\"; Note = \"#bc-ignore!\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "5"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "5"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "5"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "5"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "5"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "5"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "5"
}
}
}
},
"oer-ZB-VOx.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"None (Use global settings)\"; ObjectID = \"oer-ZB-VOx\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "لا شيء (استخدام الإعدادات العامة)"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Žádné (použít globální nastavení)"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Globale einstellungen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "None (Use global settings)"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ajustes globales"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aucun (Utiliser les param. globaux)"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "ללא (השתמש בהגדרות גלובליות)"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कोई नहीं (वैश्विक सेटिंग का उपयोग करें)"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nessuno (Usa impostazioni globali)"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "自動"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "지정 안함 (기본 설정 사용)"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Geen (Gebruik globale instellingen)"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nenhum (use configuração padrão)"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nenhum (Utilizar definições globais)"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Не использовать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hiçbiri (Genel ayarları kullan)"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Глобальні налаштування"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "无(使用全局设置)"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "無 (使用全域設定)"
}
}
}
},
"oL6-fG-vHv.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Create Web Page\"; ObjectID = \"oL6-fG-vHv\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "إنشاء صفحة ويب"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vytvořit webovou stránku"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web-Seite erstellen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Create Web Page"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Crear página web"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Créer une page Web"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "צור דף אינטרנט"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "वेब पेज बनाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Crea pagina web"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ウェブページの作成"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "웹 페이지 만들기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Webpagina maken"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Criar página Web"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Criar página da Web"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Создать веб-страницу"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web Sayfası Oluştur"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Створити веб-сторінку"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "创建为网页URL"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "建立網頁"
}
}
}
},
"Olw-nP-bQN.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Hide FSNotes\"; ObjectID = \"Olw-nP-bQN\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "اخفاء FSNotes"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Skrýt FSNotes"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes ausblenden"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Hide FSNotes"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ocultar FSNotes"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Masquer FSNotes"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הסתר את FSNotes"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes छिपाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nascondi FSNotes"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotesを非表示"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes 숨기기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verbergen FSNotes"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ocultar o FSNotes"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ocultar FSNotes"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Спрятать FSNotes"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes'u gizle"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сховати FSNotes"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "隐藏 FSNotes"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "隱藏 FSNotes"
}
}
}
},
"OOL-dM-zIE.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Code Block\"; ObjectID = \"OOL-dM-zIE\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "الاكواد البرمجية"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Blok kódu"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Blocksatz"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Code Block"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloque de código"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloc de code"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "בלוק קוד"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कोड ब्लॉक"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Blocco codice"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "コードブロック"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "코드 영역"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Codeblok"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloco de código"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloco de código"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Блок кода"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kod Bloğu"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Блок коду"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "代码块"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "程式碼區塊"
}
}
}
},
"oQE-3t-6pa.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Forward\"; ObjectID = \"oQE-3t-6pa\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "إلى الأمام"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vpřed"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vorwärts"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Forward"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Adelante"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Navigation vers l'avant"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "קדימה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "आगे"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Avanti"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "進む"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "앞으로"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vooruit"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Avançar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Avançar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вперёд"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "İleri"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вперед"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "向前"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "前進"
}
}
}
},
"OV0-om-POJ.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Print\"; ObjectID = \"OV0-om-POJ\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "طباعة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tisknout"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Drucken"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Print"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Imprimir…"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Imprimer"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הדפס"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "प्रिंट"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Stampa"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "印刷"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "프린트"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Druk af"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Imprimir"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Imprimir"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Печать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yazdır"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Роздрукувати"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "打印"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "列印"
}
}
}
},
"OwM-mh-QMV.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Find Previous\"; ObjectID = \"OwM-mh-QMV\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "البحث السابق"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hledat předchozí"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Weitersuchen (rückwärts)"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Find Previous"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Buscar anterior"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Précédente occurrence"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "מצא את הקודם"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पिछला खोजे"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Trova precedente"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "前を探す"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "이전 찾기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zoek Vorige"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Procurar anteriores"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pesquisar Anterior"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Найти предыдущий"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Öncekini Bul"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Знайти попередній"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "查找上一个"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "尋找上一個"
}
}
}
},
"Oyz-dy-DGm.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Stop Speaking\"; ObjectID = \"Oyz-dy-DGm\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "ايقاف التحدث"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zastavit předčítání"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sprachausgabe stoppen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Stop Speaking"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Detener locución"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Arrêter la diction"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הפסק הקראה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "बोलना बंद करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ferma Lettura"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "読み上げを停止"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "말하기 중단"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Stop met Praten"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Parar de falar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Parar Ditado"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Остановить диктовку"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Konuşmayı Bitir"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Зупинити диктування"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "停止朗读"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "停止朗讀"
}
}
}
},
"P2a-yk-5Rx.title" : {
"comment" : "Class = \"NSViewController\"; title = \"Layout\"; ObjectID = \"P2a-yk-5Rx\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "نسق"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rozložení"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Layout"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Layout"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Disposición"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Agencement"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "מערך"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "लेआउट"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Layout"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "レイアウト"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "레이아웃"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Indeling"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Layout"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Layout"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Интерфейс"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Düzen"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Інтерфейс"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "布局"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "版面配置"
}
}
}
},
"P4M-cL-lfo.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Indent Using:\"; ObjectID = \"P4M-cL-lfo\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "مسافة بادئة باستخدام:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Odsazovat pomocí:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Einzug mit:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Indent Using:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sangría usando:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Instantanés automatiques:"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "שימוש בהזחה:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "इंडेंट के लिए उपयोग करें:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rientro utilizzando:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "インデント:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "자동 스냅샷:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Automatische snapshots:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Indentar usando:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Recuar usando:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Отступы:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Giriş Kullanarak:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Відступ за допомогою:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "使用缩进:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "縮排方式:"
}
}
}
},
"P31-Ka-9HV.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Automatic Snapshots:\"; ObjectID = \"P31-Ka-9HV\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "لقطات تلقائية:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Automatické snímky:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Automatisches Backup:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Automatic Snapshots:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copia de seguridad automática:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clichés instantanés automatiques :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "תמונות מצב אוטומטיות:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "स्वचालित स्नैपशॉट:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Snapshot automatici:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "自動スナップショット:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "자동 스냅샷:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Automatische snapshots:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Snapshots automáticos:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Snapshots automáticos:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Стратегия резервного копирования:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Otomatik Anlık Görüntüler:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Автоматичні резервні копії:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "自动快照:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "自動快照:"
}
}
}
},
"pa3-QI-u2k.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Delete\"; ObjectID = \"pa3-QI-u2k\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "حذف"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Smazat"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Löschen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Delete"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Eliminar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Supprimer"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "מחק"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "मिटाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Elimina"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "削除"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "삭제"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verwijder"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Deletar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Eliminar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Удалить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sil"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Видалити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "删除"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "刪除"
}
}
}
},
"PdU-Em-Ugm.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Toggle Preview\"; ObjectID = \"PdU-Em-Ugm\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تبديل معاينة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Přepnout náhled"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vorschau umschalten"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Toggle Preview"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cambiar previsualización"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Afficher l'aperçu"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הצג/הסתר תצוגה מקדימה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पूर्वावलोकन टॉगल करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Passa all'anteprima"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "プレビューの切り替え"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "미리보기 토글"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Wissel voorvertoning"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Alterar pré-visualização"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Alternar pré-visualização"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Переключить предпросмотр"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Önizlemeyi Aç/Kapat"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Переключити прев'ю"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "切换预览"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "切換預覽"
}
}
}
},
"PJ2-3m-IGm.placeholderString" : {
"comment" : "Class = \"NSTextFieldCell\"; placeholderString = \"git@github.com:glushchenko/example.git\"; ObjectID = \"PJ2-3m-IGm\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "git@github.com:glushchenko/example.git"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "git@github.com:glushchenko/priklad.git"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "git@github.com:glushchenko/example.git"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "git@github.com:glushchenko/example.git"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "git@github.com:glushchenko/example.git"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "git@github.com:glushchenko/example.git"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "git@github.com:glushchenko/example.git"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "git@github.com:glushchenko/example.git"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "git@github.com:glushchenko/example.git"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "git@github.com:glushchenko/example.git"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "git@github.com:glushchenko/example.git"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "git@github.com:glushchenko/example.git"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "git@github.com:glushchenko/example.git"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "git@github.com:glushchenko/example.git"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "git@github.com:glushchenko/example.git"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "git@github.com:glushchenko/ornek.git"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "git@github.com:glushchenko/example.git"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "git@github.com:glushchenko/example.git"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "git@github.com:glushchenko/example.git"
}
}
}
},
"PLH-LL-geH.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Repeat Password:\"; ObjectID = \"PLH-LL-geH\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "اعد كتابة كلمة المرور:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zopakujte heslo:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Passwort wiederholen:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Repeat Password:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Repetir contraseña:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Retaper le mot de passe :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "אישור סיסמה:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पासवर्ड दोहराएं:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ripeti password:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "パスワードを再入力:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "확인:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Herhaal wachtwoord:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Repita senha:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Repetir palavra-passe"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Повторите пароль:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Şifreyi tekrar girin:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Пароль ще раз:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "重复密码:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "再次輸入密碼:"
}
}
}
},
"pnm-dP-GKO.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Duplicate\"; ObjectID = \"pnm-dP-GKO\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "نسخة مكررة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Duplikovat"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Duplizieren"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Duplicate"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Duplicar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dupliquer"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "שכפל"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नकल"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Duplica"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "複製"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "복제"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dupliceer"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Duplicar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Duplicar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Создать копию"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kopyala"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Дублювати"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "生成副本"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "製作複本"
}
}
}
},
"PXw-YJ-q6A.title" : {
"comment" : "Class = \"NSViewController\"; title = \"Security\"; ObjectID = \"PXw-YJ-q6A\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "الحماية"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zabezpečení"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sicherheit"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Security"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Seguridad"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sécurité"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "אבטחה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "सुरक्षा"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sicurezza"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "セキュリティ"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "보안"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Veiligheid"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Segurança"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Segurança"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Безопасность"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Güvenlik"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Безпека"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "安全性"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "安全性"
}
}
}
},
"PY8-lr-5qr.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Creation date\"; ObjectID = \"PY8-lr-5qr\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تاريخ الانشاء"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Datum vytvoření"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Erstellungsdatum"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Creation date"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fecha de creación"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Date de création"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "תאריך יצירה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "निर्माण तारीख"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Data di creazione"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "作成日"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "생성일"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aanmaakdatum"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Data de criação"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Data de criação"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Дата создания"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Oluşturulma tarihi"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Датою створення"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "创建日期"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "建立日期"
}
}
}
},
"Pzb-TG-43d.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Headers\"; ObjectID = \"Pzb-TG-43d\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kopfzeilen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Headers"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Encabezados"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "En-têtes"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "शीर्षक"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Intestazioni"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заголовки"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Başlıklar"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заголовки"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "标题"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "標題"
}
}
}
},
"PzH-8q-38O.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Delete Web Page\"; ObjectID = \"PzH-8q-38O\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "حذف صفحة الويب"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Smazat webovou stránku"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Geteilte aktualisieren"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Delete Web Page"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Eliminar página web"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Supprimer la page Web"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "מחק דף אינטרנט"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "वेब पेज हटाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Elimina pagina web"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ウェブページを削除"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "웹 페이지 삭제"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Webpagina verwijderen"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Deletar página Web"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Excluir página da Web"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Удалить веб-страницу"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web Sayfasını Sil"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Видалити веб-сторінку"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "删除网页"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "刪除網頁"
}
}
}
},
"q09-fT-Sye.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Find Next\"; ObjectID = \"q09-fT-Sye\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "بحث عن التالي"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hledat další"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Weitersuchen (vorwärts)"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Find Next"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Buscar siguiente"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Prochaine occurrence"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "מצא את הבא"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "अगला खोजे"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Trova successivo"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "次を探す"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "다음 찾기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zoek Volgende"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Procurar próximo"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pesquisar Próximo"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Найти следующий"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sonrakini Bul"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Знайти далі"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "查找下一个"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "尋找下一個"
}
}
}
},
"Q9n-yE-Ul0.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Report Bugs or Feature Requests\"; ObjectID = \"Q9n-yE-Ul0\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تبليغ عن خطأ برمجي او طلب ميزة جديدة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ohlásit chyby nebo návrhy pro zlěpšení"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Report Bugs or Feature Requests"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Report Bugs or Feature Requests"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Informar de Errores o Mejoras"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remonter des bugs ou des demandes de fonctionnalités"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "דוחות באגים ובקשות"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "समस्या या सुविधा अनुरोध की रिपोर्ट करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Segnala bug o richiedi una funzionalità"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "バグや機能要望の報告"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "버그 보고 및 기능 제안"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Meld bugs of functieverzoeken"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Reportar erros ou solicitação de funcionalidades"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Reportar Bugs ou Pedir Funcionalidades"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сообщить об ошибках"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hataları veya Özellik İsteklerini Bildirin"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Повідомити про помилки або запитати про нові функції"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "报告错误或者提交功能请求"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "回報錯誤或功能請求"
}
}
}
},
"QdU-og-lQH.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Change Creation Date\"; ObjectID = \"QdU-og-lQH\"; Note = \"#bc-ignore!\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تغيير تاريخ الإنشاء"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Změnit datum vytvoření"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Erstellungsdatum ändern"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Change Creation Date"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cambiar fecha de creación"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Modifier la date de création"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "שנה את תאריך היצירה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "निर्माण तारीख बदलें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Modifica data di creazione"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "作成日の変更"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "생성 날짜 변경"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Wijzig de aanmaakdatum"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Alterar data de criação"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Alterar data de criação"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Изменить дату создания"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Oluşturma Tarihini Değiştir"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Змінити дату створення"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "更改创建日期"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "變更建立日期"
}
}
}
},
"Qkz-nR-Fh5.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Git repository:\"; ObjectID = \"Qkz-nR-Fh5\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "أو استخدم المفتاح الخاص .ssh (موصى به):"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git repozitář:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Oder verwenden Sie einen privaten .ssh-Schlüssel (empfohlen):"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Git repository:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "O use la clave privada .ssh (recomendado):"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ou utilisez la clé privée .ssh (recommandé):"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "או השתמש במפתח פרטי .ssh (מומלץ):"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "गिट रिपोजिटरी"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Oppure usa la chiave privata .ssh (consigliato):"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "または、.ssh 秘密鍵を使用します (推奨):"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "또는 .ssh 개인 키 사용(권장):"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Of gebruik de .ssh-privésleutel (aanbevolen):"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Repositório Git:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ou use a chave privada .ssh (recomendado):"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git репозиторий:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git deposu:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Або використовуйте .ssh приватний ключ (рекомендується):"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "或使用 .ssh 私钥(推荐):"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git 儲存庫:"
}
}
}
},
"qn1-vy-8oB.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Format: yyyy-MM-dd hh.mm.ss a\"; ObjectID = \"qn1-vy-8oB\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Format: yyyy-MM-dd hh.mm.ss a"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formát: yyyy-MM-dd hh.mm.ss a"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Format: yyyy-MM-dd hh.mm.ss a"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Format: yyyy-MM-dd hh.mm.ss a"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formato: yyyy-MM-dd hh.mm.ss a"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Format: yyyy-MM-dd hh.mm.ss a"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "פורמט: yyyy-MM-dd hh.mm.ss a"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "प्रारूप: yyyy-MM-dd hh.mm.ss a"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Format: yyyy-MM-dd hh.mm.ss a"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "フォーマット: yyyy-MM-dd hh.mm.ss a"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "체재: yyyy-MM-dd hh.mm.ss a"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Format: yyyy-MM-dd hh.mm.ss a"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formato: yyyy-MM-dd hh.mm.ss a"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formato: yyyy-MM-dd hh.mm.ss a"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Формат: yyyy-MM-dd hh.mm.ss a"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Biçim: yyyy-MM-dd hh.mm.ss a"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Формат: yyyy-MM-dd hh.mm.ss a"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "格式: yyyy-MM-dd hh.mm.ss a"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "格式:yyyy-MM-dd hh.mm.ss a"
}
}
}
},
"qNE-oZ-zJr.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Back\"; ObjectID = \"qNE-oZ-zJr\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "عودة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zpět"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zurück"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Back"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Atrás"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Navigation vers l'arrière"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "אחורה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पीछे"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Indietro"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "戻る"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "뒤"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Terug"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Voltar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Voltar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Назад"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Geri"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Назад"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "返回"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "返回"
}
}
}
},
"qs2-5J-Q3n.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Show Options\"; ObjectID = \"qs2-5J-Q3n\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "عرض الاعدادات"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zobrazit možnosti"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Einstellungen anzeigen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Show Options"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ver configuración"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Afficher les options d'affichage"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הצג אפשרויות"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "विकल्प दिखाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostra opzioni vista"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "オプションを表示"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "보기 옵션"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Toon weergaveopties"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar as opções"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar opções de visualização"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Настроить вид"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Seçenekleri Göster"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Налаштування вигляду"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "显示视图选项"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "顯示選項"
}
}
}
},
"QxK-39-9yF.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Direction:\"; ObjectID = \"QxK-39-9yF\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "اتجاه:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Směr:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Richtung:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Direction:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dirección:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Direction :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "סדר:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "दिशा:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Direzione:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "方向:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "방향:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Richting:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Direção:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Direcção:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Направление:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yön:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Напрямок:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "方向:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "方向:"
}
}
}
},
"qZf-Xp-kDW.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Main Window\"; ObjectID = \"qZf-Xp-kDW\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "النافذة الرئيسية"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hlavní okno"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hauptfenster"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Main Window"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ventana principal"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fenêtre principale"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "חלון ראשי"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "मुख्य विंडो"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Finestra principale"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "メインウィンドウ"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "주 윈도우"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hoofd Venster"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Janela principal"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Janela Principal"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Главное окно"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ana Pencere"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Головне Вікно"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "主窗口"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "主視窗"
}
}
}
},
"r2R-xe-eCA.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Focus in editor when selecting note\"; ObjectID = \"r2R-xe-eCA\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "التركيز في المحرر عند اختيار المذكرة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Při výběru poznámky přepnout do editoru"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fokus im Editor bei Auswahl der Notiz"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Focus in editor when selecting note"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Empezar con la edición al seleccionar una nota"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Curseur dans l'éditeur lorsqu'une note est sélectionnée"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "התמקד בעורך בבחירת פתק"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नोट चुनते समय संपादक में फ़ोकस करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Evidenzia nell'editor quando si seleziona la nota"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ノート選択時にエディタへ移動する"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "노트 선택 시 편집기 활성화"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Focus in editor bij selecteren notitie"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Foco no editor ao selecionar a nota"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Focar no editor quando seleccionar nota"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Фокус в редактор при выборе заметки"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Not seçerken düzenleyicide odaklanın"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Фокус в редактор при виборі нотатки"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "当选中笔记时编辑器自动聚焦(笔记内容处理编辑状态)"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "選取筆記時將焦點移至編輯器"
}
}
}
},
"r69-B6-vT3.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Margin Size:\"; ObjectID = \"r69-B6-vT3\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "حجم الهامش:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Velikost okrajů:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Absatzgröße: "
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Margin Size:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tamaño del margen: "
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Taille de marge: "
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "גודל שוליים:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "मार्जिन आकार:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dimensione margine: "
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "マージン幅:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "여백 크기:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Marge grootte: "
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tamanho da margem:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tamanho da margem:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Отступ абзаца:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Marj Boyutu:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Відступ абзацу:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "边距大小: "
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "邊界大小:"
}
}
}
},
"rbD-Rh-wIN.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Check Spelling While Typing\"; ObjectID = \"rbD-Rh-wIN\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تحقق من التدقيق الإملائي أثناء الكتابة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kontrolovat pravopis během psaní"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Während der Texteingabe prüfen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Check Spelling While Typing"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Comprobar ortografía mientras se escribe"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vérifier l'orthographe pendant l'écriture"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "בדוק איות תוך כדי הקלדה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "टाइप करते समय वर्तनी जाँचें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Controlla l'ortografia durante la digitazione"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "入力中にスペルをチェック"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "입력하는 동안 맞춤법 검사"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Controleer Spelling Tijdens Typen"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verificar ortografia enquanto digita"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verificar gramática durante a escrita"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Проверять во время набора"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yazarken Yazım Denetimi Yapın"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перевіряти правопис під час набору"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "键入时检查拼写"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "輸入時同步檢查拼字"
}
}
}
},
"rbM-i0-QFp.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Reset\"; ObjectID = \"rbM-i0-QFp\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "إعادة ضبط"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Resetovat"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zurücksetzen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Reset"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Reiniciar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Réinitialiser"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "אִתחוּל"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "रीसेट करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ripristina"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "リセット"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "초기화"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Resetten"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Resetar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Redefinir"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сбросить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sıfırla"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Скинути"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "重置"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "重設"
}
}
}
},
"RdI-N4-pR2.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Trash\"; ObjectID = \"RdI-N4-pR2\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "الملهملات"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Koš"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Papierkorb"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Trash"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Papelera"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Corbeille"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "פח אשפה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कूडा"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cestino"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ゴミ箱"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "휴지통"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Prullenmand"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lico"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lixo"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Корзина"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Çöp"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сміття"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "回收站"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "垃圾桶"
}
}
}
},
"Rg2-j1-Foz.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Copy URL\"; ObjectID = \"Rg2-j1-Foz\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "نسخ URL"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kopírovat URL"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "URL kopieren"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Copy URL"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copiar enlace"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copier l'URL"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "העתק כתובת"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "यूआरएल कॉपी करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copia URL"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "URLをコピー"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "URL 복사"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kopieer URL"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copiar URL"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copiar endereço URL"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Скопировать ссылку"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "URLyi Kopyala"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Скопіювати посилання"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "拷贝 URL"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "複製網址"
}
}
}
},
"rgM-f4-ycn.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Smart Dashes\"; ObjectID = \"rgM-f4-ycn\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "شرطات ذكية"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Inteligentní pomlčky"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Intelligente Bindestriche"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Smart Dashes"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Guiones inteligentes"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tirets intelligents"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "מיקוף חכם"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "स्मार्ट डैश"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Trattini Smart"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "スマートダッシュ"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "스마트 대시"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Slimme Streepjes"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Traços inteligentes"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Traços Inteligentes"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Смарт-тире"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Akıllı çizgi"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Розумні тире"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "智能破折号"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "智慧型破折號"
}
}
}
},
"rHB-xF-GgG.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Sort By\"; ObjectID = \"rHB-xF-GgG\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "ترتيب حسب"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Řadit podle"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sortiere nach"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Sort By"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordenar por"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Trier par"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "מיין לפי"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "इसके अनुसार क्रमबद्ध करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordina per"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "整頓順序"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "다음으로 정렬"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sorteer op"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordernar por"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordenar por"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Упорядочить по"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Göre sırala"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сортувати за"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "排序方式"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "排序方式"
}
}
}
},
"Ri7-Yr-qyB.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Clone\"; ObjectID = \"Ri7-Yr-qyB\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clone"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Klonovat"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clone"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Clone"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clone"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clone"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clone"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "क्लोन"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clone"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clone"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clone"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clone"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clonar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clone"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Клонировать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Klon"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clone"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "克隆"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "複製專案"
}
}
}
},
"RSs-wb-GNg.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Lock/Unlock\"; ObjectID = \"RSs-wb-GNg\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "فقل/فتح الفقل"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zamknout/odemknout"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sperren/Entsperren"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Lock/Unlock"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloquear/desbloquear"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verrouiller/déverrouiller"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "נעל/פתח"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "लॉक/अनलॉक"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Blocca/sblocca"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ロック/ロックの削除"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "잠금/잠금 해제"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vergrendel/ontgrendel"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloquear/desbloquear"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloquear/desbloquear"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заблокировать/разблокировать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kilitle/Kilidi Aç"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заблокувати/розблокувати"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "锁定/解锁"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "鎖定/解鎖"
}
}
}
},
"rSZ-Wo-Rtj.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"System\"; ObjectID = \"rSZ-Wo-Rtj\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "النظام"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Systém"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "System"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "System"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sistema"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Système"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "מערכת"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "सिस्टम"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sistema"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "システム"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "시스템"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Systeem"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sistema"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sistema"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Система"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sistem"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Системна"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "系统"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "系統"
}
}
}
},
"Ruw-6m-B2m.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Select All\"; ObjectID = \"Ruw-6m-B2m\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تحديد الكل"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vybrat vše"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Alles auswählen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Select All"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Seleccionar todo"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tout sélectionner"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "בחר הכל"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "सबका चयन करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Seleziona Tutto"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "すべてを選択"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "모두 선택"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Selecteer Alles"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Selecionar todos"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Seleccionar todos"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Выбрать всё"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hepsini Seç"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вибрати все"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "选择全部"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "全選"
}
}
}
},
"RwR-P0-ycK.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Delete Folder\"; ObjectID = \"RwR-P0-ycK\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "حذف المجلد"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Smazat složku"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordner löschen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Delete Folder"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Eliminar carpeta"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Supprimer le dossier"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "מחק תיקיה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "फोल्डर हटाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Elimina cartella"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "フォルダを削除"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "폴더 삭제"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verwijder map"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Deletar pasta"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Eliminar pasta"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Удалить директорию"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dosyayı Sİl"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Видалити директорію"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "删除文件夹"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "刪除資料夾"
}
}
}
},
"rXU-X3-UjC.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Reveal in Finder\"; ObjectID = \"rXU-X3-UjC\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "فتح المجلد"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zobrazit ve Finderu"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "In Finder anzeigen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Reveal in Finder"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar en el Finder"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Localiser dans le Finder"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הצג ב-Finder"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "Finder में दिखाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostra nel Finder"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Finderに表示"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Finder에서 보기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Onthul in Finder"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Revelar no Finder"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Realçar no Finder"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показать в Finder"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Finder'da ortaya çıkar"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показати в Finder"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "在访达中显示"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "顯示於 Finder"
}
}
}
},
"rzB-ln-uyl.placeholderString" : {
"comment" : "Class = \"NSSecureTextFieldCell\"; placeholderString = \"passphrase\"; ObjectID = \"rzB-ln-uyl\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "passphrase"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "přístupová fráze"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "passphrase"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "passphrase"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "passphrase"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "passphrase"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "passphrase"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पासफ्रेज"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "passphrase"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "passphrase"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "passphrase"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "passphrase"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "frase secreta"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "passphrase"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "passphrase"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Parola"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "passphrase"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "passphrase"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "通關密語"
}
}
}
},
"S0p-oC-mLd.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Jump to Selection\"; ObjectID = \"S0p-oC-mLd\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "الانتقال الى المحدد"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Přeskočit na výběr"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zur Auswahl"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Jump to Selection"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ir a la selección"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sauter vers la sélection"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "קפוץ לבחירה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "चयन पर जाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vai alla selezione"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Jump to Selection"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "선택 부분으로 이동"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Spring naar Selectie"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pular para seleção"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Saltar para a selecção"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перейти к выбранному"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Seçime Git"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перейти до вибраного"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "跳到所选内容"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "跳至選取範圍"
}
}
}
},
"s6A-tQ-Sbe.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Bring All to Front\"; ObjectID = \"s6A-tQ-Sbe\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "أحضر الكل إلى الأمام"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Převést vše do popředí"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Alle nach vorne bringen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Bring All to Front"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Traer todo al frente"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tout afficher en premier plan"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הבא הכל קדימה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "सबको सामने लाये"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Porta tutto in primo piano"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "すべてを手前に移動"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "모두 앞으로 가져오기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Breng alles naar voren"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Trazer todos para frente"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Trazer todos para a frente"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Переместить на передний план"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hepsini Öne Getir"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перемістити все на передній план"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "前置全部窗口"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "將此程式所有視窗移至最前"
}
}
}
},
"S8Z-Js-fwB.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Add External Folder...\"; ObjectID = \"S8Z-Js-fwB\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "ارفاق تخزين..."
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Přidat externí složku"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Speicher anschließen..."
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Add External Folder..."
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Adjuntar almacenamiento..."
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Attacher un stockage..."
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הוסף תיקיה חיצונית..."
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "बाह्य फ़ोल्डर जोड़ें..."
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Collega archivio..."
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "外部フォルダを追加…"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "저장소 추가..."
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Koppelen opslag..."
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Adicionar pasta externa..."
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Adicionar armazenamento..."
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Подключить хранилище..."
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Harici Klasör Ekle..."
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Підключити сховище..."
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "附件存储..."
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "加入外部資料夾…"
}
}
}
},
"sAn-Wm-FfY.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Commit/Push every\"; ObjectID = \"sAn-Wm-FfY\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "النسخ الاحتياطي كل"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Commit/push každých"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sichern Sie jeden"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Commit/Push every"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Respaldar cada"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sauvegarder toutes les "
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "גבה אוטומטית כל"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कमिट/पुश आवृत्ति"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Salva ogni"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "次の間隔でバックアップ"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "백업"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Back-up elke"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Commi/Push todos"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cópia de seg. a cada"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Копия каждый"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Her Taahhüt Et/İt"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Резервна копія кожну"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "提交或推送间隔每"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "自動提交/推送頻率"
}
}
}
},
"Scc-aD-CFQ.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Notes List:\"; ObjectID = \"Scc-aD-CFQ\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "قائمة الملاحظات"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Seznam poznámek:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notizlist:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Notes List:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lista de notas:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Liste de notes :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "רשימת פתקים:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नोट सूची:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lista Note:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ノート一覧:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "노트 목록:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notitielijst:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lista de notas:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lista de notas"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Список заметок:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Not Listesi:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Лист нотаток:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "笔记列表:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "筆記清單:"
}
}
}
},
"sdE-ZM-6cq.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Move Up in the Sidebar\"; ObjectID = \"sdE-ZM-6cq\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تحرك لأعلى في الشريط الجانبي"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Posunout nahoru v bočním panelu"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "In der Seitenleiste aufsteigen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Move Up in the Sidebar"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mover arriba en la barra lateral"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Élément précédent de la barre latérale"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "עבור למעלה בסרגל הצד"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "साइडबार में ऊपर जाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Muovi in Alto nella Sidebar"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "サイドバー項目を上に移動"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "사이드바에서 위로 이동"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Omhoog gaan in de zijbalk"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mover para cima no menu lateral"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Subir na barra lateral"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перейти вверх в боковой панели"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kenar Çubuğunda Yukarı Çık"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перейти вгору на бічній панелі"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "在侧边栏中向上移动"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "在側邊欄中上移"
}
}
}
},
"SdL-vK-KjH.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Window\"; ObjectID = \"SdL-vK-KjH\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "نافذة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Okno"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fenster"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Window"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ventana"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fenêtre"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "חלון"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "विंडो"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Finestra"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ウィンドウ"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "윈도우"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Venster"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Janela"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Janela"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Window"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pencere"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вікно"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "窗口"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "視窗"
}
}
}
},
"SDz-2X-4yJ.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Reset Caches\"; ObjectID = \"SDz-2X-4yJ\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "إعادة تعيين ذاكرة التخزين المؤقت"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vyprázdnit cache"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Caches zurücksetzen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Reset Caches"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Restablecer cachés"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Réinitialiser les caches"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "אפס מטמונים"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कैश रीसेट करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ripristino delle cache"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "キャッシュのリセット"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "캐시 초기화"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Caches resetten"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Redefinir caches"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Repor caches"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сбросить кэш"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Önbellekleri Sıfırla"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Скинути кеші"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "重置缓存"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "重設快取"
}
}
}
},
"SeY-r8-n3w.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"File\"; ObjectID = \"SeY-r8-n3w\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "ملف"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Soubor"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Datei"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "File"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Archivo"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fichier"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "קובץ"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "फ़ाइल"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "File"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ファイル"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "파일"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bestand"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Arquivo"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ficheiro"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Файл"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dosya"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Файл"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "文件"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "檔案"
}
}
}
},
"Shc-VO-eTc.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Code Font\"; ObjectID = \"Shc-VO-eTc\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "كود الخط"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Písmo kódu"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Code Font"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Code Font"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Code Font"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Police de code"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "גופן קוד"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कोड फ़ॉन्ट"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Font Codice"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "コードフォント"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "코드 서체"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Code Lettertype"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Código fonte"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tipo de letra de código"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Шрифт кода"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kod Yazı Tipi"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Шрифт коду"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "代码字体"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "程式碼字體"
}
}
}
},
"Snd-dJ-uj5.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"History\"; ObjectID = \"Snd-dJ-uj5\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تاريخ"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Historie"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Die geschichte"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "History"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Historia"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Historique"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "היסטוריה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "इतिहास"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cronologia"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "履歴"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "변경 이력"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Geschiedenis"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Histórico"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Histórico"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "История"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tarih"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Історія"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "笔记历史版本"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "歷程記錄"
}
}
}
},
"SpX-N8-9td.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"solarized\"; ObjectID = \"SpX-N8-9td\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "solarized"
}
},
"ja" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Solarized Light"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Salaried-light"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "solarized"
}
}
},
"shouldTranslate" : false
},
"SrH-fe-Hog.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"New Folder\"; ObjectID = \"SrH-fe-Hog\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "مجلد جديد"
}
},
"cs" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Vytvořit složku"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Neuer Ordner"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "New Folder"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nueva carpeta"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nouveau dossier"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "תיקיה חדשה"
}
},
"hi" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "फोल्डर बनाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nuova cartella"
}
},
"ja" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "フォルダを作成"
}
},
"ko" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "새로운 폴더"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Nieuwe map"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Criar pasta"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Nova pasta"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Создать директорию"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Klasör Oluştur"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Нова директорія"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "新建文件夹"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "新增資料夾"
}
}
}
},
"ssC-ed-19K.title" : {
"comment" : "Class = \"NSViewController\"; title = \"Editor\"; ObjectID = \"ssC-ed-19K\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "المحرر"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Editor"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Editor"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Editor"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Editor"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Éditeur"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "עורך"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "संपादक"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Editor"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "エディタ"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "편집기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Editor"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Editor"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Editor"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Редактор"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Editör"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Редактор"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "编辑器"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "編輯器"
}
}
}
},
"SSY-US-gmJ.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Show icon in menu bar\"; ObjectID = \"SSY-US-gmJ\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "عرض الايقونة في شريط القوائم"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zobrazit ikonu v řádku nabídek"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Icon in der Menüleiste anzeigen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Show icon in menu bar"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar icono en la barra de menús"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Afficher l'icône dans la barre de menu"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הצג צלמית בשורת הטפריטים"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "मेनू बार में आइकन दिखाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostra icona nella barra del menù"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "メニューバーにアイコンを表示"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "메뉴바에서 아이콘 보기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Toon icoon in menubalk"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar ícone na barra de menu"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar ícone na barra de menu"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показывать иконку в меню баре"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Menü çubuğunda simgeyi göster"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Відображати іконку в меню барі"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "在菜单栏中显示图标"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "在選單列顯示圖示"
}
}
}
},
"STm-3f-GNu.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Move Selected Lines Down\"; ObjectID = \"STm-3f-GNu\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ausgewählte Zeilen nach unten verschieben"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Move Selected Lines Down"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mover líneas seleccionadas hacia abajo"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Déplacer les lignes sélectionnées vers le bas"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "चुनी हुई पंक्तियों को नीचे ले जाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sposta righe selezionate verso il basso"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Переместить выбранные строки вниз"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Seçili Satırları Aşağı Taşı"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перемістити вибрані рядки вниз"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "选中行向下移动"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "將選取的行下移"
}
}
}
},
"sWS-bo-99f.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Dylan Seeger — https://www.lovably.com\\nOlena Hlushcneko\"; ObjectID = \"sWS-bo-99f\"; Note = \"#bc-ignore!\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dylan Seeger — https://www.lovably.com\nOlena Hlushcneko"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dylan Seeger — https://www.lovably.com\nOlena Hlushcneko"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dylan Seeger — https://www.lovably.com\nOlena Hlushcneko"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Dylan Seeger — https://www.lovably.com\nOlena Hlushcneko"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dylan Seeger — https://www.lovably.com\nOlena Hlushcneko"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dylan Seeger — https://www.lovably.com\nOlena Hlushcneko"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dylan Seeger — https://www.lovably.com\nOlena Hlushcneko"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dylan Seeger — https://www.lovably.com\nOlena Hlushcneko"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dylan Seeger — https://www.lovably.com\nOlena Hlushcneko"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dylan Seeger — https://www.lovably.com\nOlena Hlushcneko"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dylan Seeger — https://www.lovably.com\nOlena Hlushcneko"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dylan Seeger — https://www.lovably.com\nOlena Hlushcneko"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dylan Seeger — https://www.lovably.com\nOlena Hlushcneko"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dylan Seeger — https://www.lovably.com\nOlena Hlushcneko"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dylan Seeger — https://www.lovably.com\nOlena Hlushcneko"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dylan Seeger — https://www.lovably.com\nOlena Hlushcneko"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dylan Seeger — https://www.lovably.com\nOlena Hlushcneko"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dylan Seeger — https://www.lovably.com\nOlena Hlushcneko"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dylan Seeger — https://www.lovably.com\nOlena Hlushcneko"
}
}
}
},
"t3f-wS-BqN.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Automatic iCloud Drive conflicts resolution\"; ObjectID = \"t3f-wS-BqN\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "حل تعارضات iCloud Drive تلقائيًا"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Automatické řešení konfliktů na iCloud Drive"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Automatische Auflösung von iCloud Drive-Konflikten"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Automatic iCloud Drive conflicts resolution"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Resolver automáticamente conflictos de iCloud Drive"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Résolution automatique des conflits avec iCloud Drive"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "פתור אוטומטית התנגשויות iCloud Drive"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "स्वचालित iCloud ड्राइव विवाद समाधान"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Risoluzione automatica dei conflitti di iCloud Drive"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Driveの競合を自動的に解決する"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive 충돌 자동 해결"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Automatisch iCloud Drive-conflicten oplossen"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Resolva automaticamente conflitos do iCloud Drive"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Resolva automaticamente conflitos do iCloud Drive"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Автоматически разрешать конфликты iCloud Drive"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Otomatik iCloud Drive çakışma çözümü"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Автоматичне вирішення конфліктів у iCloud Drive"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "自动解决 iCloud Drive 冲突"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "自動解決 iCloud 雲碟衝突"
}
}
}
},
"TCI-Xs-mwm.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Descending\"; ObjectID = \"TCI-Xs-mwm\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تنازلي"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sestupně"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Absteigend"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Descending"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Descendiendo"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Descendant"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "יורד"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "अवरोही"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Decrescente"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "降順"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "내림차순"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aflopend"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Descendente"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Descendente"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Нисходящее"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Azalan"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Низхідний"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "降序"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "遞減"
}
}
}
},
"TfH-z4-HHY.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \".txt\"; ObjectID = \"TfH-z4-HHY\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : ".txt"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : ".txt"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : ".txt"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : ".txt"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : ".txt"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : ".txt"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : ".txt"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : ".txt"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : ".txt"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : ".txt"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : ".txt"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : ".txt"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : ".txt"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : ".txt"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : ".txt"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : ".txt"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : ".txt"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : ".txt"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : ".txt"
}
}
}
},
"Tjy-Pz-wrj.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Appearance:\"; ObjectID = \"Tjy-Pz-wrj\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "مظهر خارجي:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vzhled:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Design:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Appearance:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Apariencia:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Apparence :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "מראה:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "स्वरूप:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aspetto:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "外観モード:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "외관:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verschijning:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aparência:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aparência:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Тема:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dış görünüş:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Тема:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "外观:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "外觀:"
}
}
}
},
"TKE-yB-wPs.ibShadowedToolTip" : {
"comment" : "Class = \"NSImageView\"; ibShadowedToolTip = \"In memory of Mars. ? - 25.08.2022\"; ObjectID = \"TKE-yB-wPs\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "In memory of Mars. ? - 25.08.2022"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Věnování: Mars. ?–25.08.2022"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "In memory of Mars. ? - 25.08.2022"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "In memory of Mars. ? - 25.08.2022"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "In memory of Mars. ? - 25.08.2022"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "In memory of Mars. ? - 25.08.2022"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "In memory of Mars. ? - 25.08.2022"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "मंगल की याद में. ? - 25.08.2022"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "In memory of Mars. ? - 25.08.2022"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "In memory of Mars. ? - 25.08.2022"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "In memory of Mars. ? - 25.08.2022"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "In memory of Mars. ? - 25.08.2022"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Em memória de Mars. ? - 25.08.2022"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "In memory of Mars. ? - 25.08.2022"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "В память о Марсе. ? - 25.08.2022"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mars'ın anısına. ? - 25.08.2022"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "In memory of Mars. ? - 25.08.2022"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "In memory of Mars. ? - 25.08.2022"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "紀念 Mars。? - 2022.08.25"
}
}
}
},
"tMJ-Dj-OZc.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"First line as title\"; ObjectID = \"tMJ-Dj-OZc\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "اول سطر كعنوان"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "První řádek jako nadpis"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Erste Zeile als Titel"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "First line as title"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Primera línea como título"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Première ligne comme titre"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "שורה ראשונה ככותרת"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "शीर्षक के रूप में पहली पंक्ति"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Prima riga come titolo"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "最初の行をタイトルとして使用"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "첫 줄을 제목으로 사용"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Eerste regel als titel"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Primeira linha como título"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Primeira linha como título"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Первая строка как заголовок"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Başlık olarak ilk satır"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перший рядок як заголовок"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "将内容第一行提取为标题"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "使用第一行作為標題"
}
}
}
},
"tR0-Uj-4tB.title" : {
"comment" : "Class = \"NSTabViewController\"; title = \"Preferences\"; ObjectID = \"tR0-Uj-4tB\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "التفضيلات"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Předvolby"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Einstellungen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Preferences"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Preferencias"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Préférences"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "העדפות"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "प्राथमिकताएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Preferenze"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "設定"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "환경설정"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Voorkeuren"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Preferências"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Preferências"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Настройки"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tercihler"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Налаштування"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "偏好设置"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "偏好設定"
}
}
}
},
"tRr-pd-1PS.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Data Detectors\"; ObjectID = \"tRr-pd-1PS\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "كاشفات البيانات"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Detektory dat"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Datendetektoren"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Data Detectors"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Detectores de datos"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Détecteurs de données"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "גלאי נתונים"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "डेटा डिटेक्टर"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rilevatori di dati"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "データ検出"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "데이터 탐색기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Data Detectoren"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Detecção de data"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Detectores de dados"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Детекторы данных"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Veri Dedektörleri"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Детектори даних"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "数据检测器"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "資料偵測器"
}
}
}
},
"tZ6-GT-LxK.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Pull every\"; ObjectID = \"tZ6-GT-LxK\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pull every"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pull každých"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pull every"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Pull every"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pull every"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tirez chaque"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pull every"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पुल आवृत्ति"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pull every"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pull every"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pull every"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pull every"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pull todos"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pull every"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Подтягивать каждые"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Her birini çek"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pull every"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "拉取分支每隔"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "每隔…拉取 "
}
}
}
},
"u88-5C-vTe.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Open\"; ObjectID = \"u88-5C-vTe\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "افتح في نافذة جديدة"
}
},
"cs" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Otevřít v novém okně"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "In neuem Fenster öffnen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Open"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Abrir en Nueva ventana"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ouvrir dans une nouvelle fenêtre"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "פתח בחלון חדש"
}
},
"hi" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "नई विंडो में खोलें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Apri in una nuova finestra"
}
},
"ja" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "新しいウィンドウで開きます"
}
},
"ko" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "새 창에서 열기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Openen in een nieuw venster"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Abrir em nova janela"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Abrir em nova janela"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Открыть в новом окне"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yeni Pencerede Aç"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Відкрити у новому вікні"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "在新窗口中打开"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "開啟"
}
}
}
},
"UdE-8N-Qit.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Label\"; ObjectID = \"UdE-8N-Qit\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Label"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Štítek"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Label"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Label"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Label"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Label"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Label"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "लेबल"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Label"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Label"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Label"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Label"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Etiqueta"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Label"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Label"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Etiket"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ярлик"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "标签"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "標籤"
}
}
}
},
"UEZ-Bs-lqG.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Capitalize\"; ObjectID = \"UEZ-Bs-lqG\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تكبير"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Velká počáteční písmena"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Großbuchstaben"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Capitalize"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mayúsculas iniciales"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ajouter les majuscules aux mots"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "אות ראשונה גדולה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "मूल बनाए"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tutte le iniziali Maiuscole"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "語頭を大文字にする"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "대문자로 만들기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Met hoofdletters schrijven"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Capitalizar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Capitalizar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Озаглавить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Büyük harfle yazmak"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Усі прописні"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "首字母大写"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "首字大寫"
}
}
}
},
"UFh-mf-ZKG.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Light\"; ObjectID = \"UFh-mf-ZKG\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "مشمس"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Světlý"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hell"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Light"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Claro"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clair"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "בהיר"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "Light"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Chiaro"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ライト"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "라이트"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Licht"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Claro"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Claro"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Светлая"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Işık"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Світла"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "浅色"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "淺色"
}
}
}
},
"uHf-35-KHR.placeholderString" : {
"comment" : "Class = \"NSTextFieldCell\"; placeholderString = \"22\"; ObjectID = \"uHf-35-KHR\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "22"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "22"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "22"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "22"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "22"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "22"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "22"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "22"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "22"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "22"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "22"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "22"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "22"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "22"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "22"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "22"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "22"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "22"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "22"
}
}
}
},
"Ukg-MO-eaB.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Code Span\"; ObjectID = \"Ukg-MO-eaB\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "امتداد الرمز"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Úsek kódu"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Codespanne"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Code Span"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Intervalo de código"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Code Span"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "קוד מוטבע"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कोड स्पैन"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Intervallo di Codice"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "インラインコード"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "코드 들여쓰기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Code inline"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Código de span"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lapso de código"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Диапазон кода"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kod aralığı"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Проміжок коду"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "代码缩进"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "程式碼區段"
}
}
}
},
"UMi-Hx-Z1c.title" : {
"comment" : "Class = \"NSMenu\"; title = \"Headers\"; ObjectID = \"UMi-Hx-Z1c\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kopfzeilen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Headers"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Encabezados"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "En-têtes"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "शीर्षक"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Intestazioni"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заголовки"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Başlıklar"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заголовки"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "标题"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "標題"
}
}
}
},
"uMZ-sI-7ja.title" : {
"comment" : "Class = \"NSMenu\"; title = \"File\"; ObjectID = \"uMZ-sI-7ja\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "ملف"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Soubor"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Datei"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "File"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Archivo"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fichier"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "קובץ"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "फ़ाइल"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "File"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ファイル"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "파일"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bestand"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Arquivo"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ficheiro"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Файл"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dosya"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Файл"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "文件"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "檔案"
}
}
}
},
"uQ1-ej-ufE.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Copy URL\"; ObjectID = \"uQ1-ej-ufE\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "نسخ URL"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kopírovat URL"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "URL kopieren"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Copy URL"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copiar enlace"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copier l'URL"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "העתק כתובת"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "यूआरएल कॉपी करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copia URL"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "URLをコピー"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "URL 복사"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kopieer URL"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copiar URL"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copiar endereço URL"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Скопировать ссылку"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "URLyi Kopyala"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Скопіювати посилання"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "拷贝URL"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "複製網址"
}
}
}
},
"uQy-DD-JDr.title" : {
"comment" : "Class = \"NSMenu\"; title = \"FSNotes\"; ObjectID = \"uQy-DD-JDr\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "FSNotes"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
}
}
},
"uRl-iY-unG.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Cut\"; ObjectID = \"uRl-iY-unG\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "قص"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vyjmout"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ausschneiden"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Cut"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cortar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Couper"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "גזור"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "काटे"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Taglia"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "カット"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "오려두기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Knip"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cortar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cortar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вырезать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kes"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вирізати"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "剪切"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "剪下"
}
}
}
},
"v1K-9W-2aB.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"github\"; ObjectID = \"v1K-9W-2aB\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "github"
}
}
},
"shouldTranslate" : false
},
"v9k-wu-2xL.placeholderString" : {
"comment" : "Class = \"NSTextFieldCell\"; placeholderString = \"empty log\"; ObjectID = \"v9k-wu-2xL\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "empty log"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "empty log"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "empty log"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "empty log"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "empty log"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "empty log"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "empty log"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "खाली लॉग"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "empty log"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "empty log"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "empty log"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "empty log"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "log vazio"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "empty log"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "empty log"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Boş Log"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "empty log"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "empty log"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "清空記錄"
}
}
}
},
"Vdr-fp-XzO.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Hide Others\"; ObjectID = \"Vdr-fp-XzO\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "إخفاء الآخرين"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Skrýt ostatní"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Alle andere Apps verstecken"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Hide Others"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ocultar otros"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Masquer les autres"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הסתר אחרים"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "अन्य को छिपाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nascondi le altre finestre"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ほかを非表示"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "기타 가리기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verberg anderen"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ocultar outros"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ocultar outros"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Спрятать другие"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Diğerlerini Gizle"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Приховати інші"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "隐藏其它"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "隱藏其他"
}
}
}
},
"Ve2-qz-vtH.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Lock on sleep\"; ObjectID = \"Ve2-qz-vtH\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "غلق عند النوم"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zamknout při uspání"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Im Schlafmodus sperren"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Lock on sleep"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloquar al entrar en reposo"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verrouiller au passage en veille"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "נעל במעבר למצב שינה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "स्लीप पर लॉक करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Blocca se in sospensione"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "スリープ時"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "잠자기 시 잠금"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vergrendel bij slapen"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloquear no repouso"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloquear ao suspender"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заблокировать в режиме сна"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Uyku modunda kilitle"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заблокувати при засипанні"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "系统休眠后自动锁定"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "睡眠時鎖定"
}
}
}
},
"vfT-nF-vst.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Or use .ssh private key:\"; ObjectID = \"vfT-nF-vst\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "أو استخدم المفتاح الخاص .ssh:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nebo použijte soukromý .ssh klíč:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Oder verwenden Sie einen privaten .ssh-Schlüssel:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Or use .ssh private key:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "O use la clave privada .ssh:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ou utilisez la clé privée .ssh:"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "או השתמש במפתח פרטי .ssh:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "या .ssh निजी कुंजी का उपयोग करें:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Oppure usa la chiave privata .ssh:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "または、.ssh 秘密鍵を使用します。"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "또는 .ssh 개인 키를 사용하십시오."
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Of gebruik de .ssh-privésleutel:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "ou use a chave privada .ssh"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ou use a chave privada .ssh:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Или используйте закрытый ключ .ssh:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "veya .ssh özel anahtarını kullanın:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Або використовуйте .ssh приватний ключ:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "或使用 .ssh 私钥:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "或使用 .ssh 私密金鑰:"
}
}
}
},
"VJs-0B-jGe.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Ask commit message on note save\"; ObjectID = \"VJs-0B-jGe\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ask commit message on note save"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ptát se na popisek commitu při uložení poznámky"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ask commit message on note save"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Ask commit message on note save"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ask commit message on note save"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ask commit message on note save"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ask commit message on note save"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नोट सेव करने पर कमिट संदेश पूछें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ask commit message on note save"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ask commit message on note save"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ask commit message on note save"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ask commit message on note save"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pedir mensagem de confirmação ao salvar notas"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ask commit message on note save"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Запрашивать название коммита перед сохранением заметки"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Not kaydetmede öneri mesajını sor"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ask commit message on note save"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "在笔记保存时询问提交消息"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "儲存筆記時詢問提交訊息"
}
}
}
},
"vmV-6d-7jI.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Make Upper Case\"; ObjectID = \"vmV-6d-7jI\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "جعله حروف كبيرة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Převést na velká písmena"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Großschreiben"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Make Upper Case"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Todo en mayúsculas"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Passer en capitales"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הפוך לאותיות גדולות"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "अपर केस बनाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rendi tutto Maiuscolo"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "大文字にする"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "대문자로 만들기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Maak Hoofdletters"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tornar maiúsculas"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Transformar em Maiúsculas"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "В верхний регистр"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Büyük Harf Yap"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Верхній регістр"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "变为大写"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "變更為大寫"
}
}
}
},
"vrs-XL-lyE.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Move Down in the Sidebar\"; ObjectID = \"vrs-XL-lyE\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تحرك لأسفل في الشريط الجانبي"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Posunout dolů v bočním panelu"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "In der Seitenleiste nach unten gehen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Move Down in the Sidebar"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mover abajo en la barra lateral"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Élément suivant de la barre latérale"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "עבור למטה בסרגל הצד"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "साइडबार में नीचे जाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Muovi in Basso nella Sidebar"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "サイドバー項目を下に移動"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "사이드바에서 아래로 이동"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Naar beneden verplaatsen in de zijbalk"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mover para baixo no menu lateral"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Descer na barra lateral"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перейти вниз в боковой панели"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kenar Çubuğunda Aşağıya Hareket Et"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перейти вниз на бічній панелі"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "在侧边栏中向下移动"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "在側邊欄中下移"
}
}
}
},
"VV2-X2-moA.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"*\"; ObjectID = \"VV2-X2-moA\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "*"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "*"
}
}
},
"shouldTranslate" : false
},
"Vwq-Ek-K2v.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Focus on search bar when ESC is pressed\"; ObjectID = \"Vwq-Ek-K2v\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "ركز على شريط البحث عند الضغط على ESC"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Stisknutím Esc přepnout do vyhledávání"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fokus auf Suchleiste, wenn ESC gedrückt wird"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Focus on search bar when ESC is pressed"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Utilizar la barra de búsqueda al presionar la tecla ESC"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Focus on Search bar when ESC is pressed"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "התמקד בשורת החיפוש בהקשת Esc"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "ESC दबाने पर खोज बार पर ध्यान केंद्रित करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Evidenzia la barra di ricerca quando premi ESC"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Escボタンを押して検索バーに移動"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "ESC를 눌렀을 때 검색창에 초점 맞추기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Focus op zoekbalk wanneer ESC wordt ingedrukt"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Focar na barra de pesquisa quando ESC é pressionado"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Focar na barra de pesquisa quando pressionar ESC"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Фокус на поиске по ESC"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "ESC tuşuna basıldığında arama çubuğuna odaklan"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Фокус на пошуку по ESC"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "按下 ESC 时聚焦于搜索栏"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "按下 ESC 時將焦點移至搜尋列"
}
}
}
},
"vZO-Tx-X1j.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Create Web Page\"; ObjectID = \"vZO-Tx-X1j\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "إنشاء صفحة ويب"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vytvořit webovou stránku"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Online teilen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Create Web Page"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Crear página web"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Créer une page Web"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "צור דף אינטרנט"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "वेब पेज बनाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Crea pagina web"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ウェブページの作成"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "웹 페이지 만들기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Webpagina maken"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Criar página Web"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Criar página da Web"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Создать веб-страницу"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web Sayfası Oluştur"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Створити веб-сторінку"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "创建为网页"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "建立網頁"
}
}
}
},
"w7R-OL-Nfh.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Lock Folder\"; ObjectID = \"w7R-OL-Nfh\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "قفل المجلد"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zamknout složku"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordner sperren"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Lock Folder"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloquear carpeta"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verrouiller le dossier"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "נעל תיקייה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "फ़ोल्डर लॉक करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Blocca cartella"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "フォルダのロック"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "폴더 잠금"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Map vergrendelen"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloquear pasta"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bloquear pasta"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заблокировать директорию"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Klasörü Kilitle"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заблокувати папку"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "锁定文件夹"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "鎖定資料夾"
}
}
}
},
"W48-6f-4Dl.title" : {
"comment" : "Class = \"NSMenu\"; title = \"Edit\"; ObjectID = \"W48-6f-4Dl\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تعديل"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Úpravy"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bearbeiten"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Edit"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Editar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Éditer"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "עריכה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "संपादन"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Modifica"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "編集"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "편집"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Edit"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Editar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Editar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Редактировать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Düzzenle"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Редагування"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "编辑"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "編輯"
}
}
}
},
"wa2-sX-NOx.placeholderString" : {
"comment" : "Class = \"NSSecureTextFieldCell\"; placeholderString = \"optional\"; ObjectID = \"wa2-sX-NOx\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "اختياري"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "nepovinné"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "optional"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "optional"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "opcional"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "optionnelle"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "אופציונאלי"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "वैकल्पिक"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "opzionale"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "オプション"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "선택 과목"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "optioneel"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Opcional"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "opcional"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "необязательный"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "isteğe bağlı"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "необов'язково"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "可选的"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "選填"
}
}
}
},
"wDP-Yg-13R.placeholderString" : {
"comment" : "Class = \"NSPathCell\"; placeholderString = \"id_rsa key is not selected\"; ObjectID = \"wDP-Yg-13R\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "~/.ssh/id_rsa"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "id_rsa klíč není vybraný"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "~/.ssh/id_rsa"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "id_rsa key is not selected"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "~/.ssh/id_rsa"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "~/.ssh/id_rsa"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "~/.ssh/id_rsa"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "id_rsa कुंजी चयनित नहीं है"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "~/.ssh/id_rsa"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "~/.ssh/id_rsa"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "~/.ssh/id_rsa"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "~/.ssh/id_rsa"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "id_rsa key não foi selecionado"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "~/.ssh/id_rsa"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ключ id_rsa не выбран"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "id_rsa anahtarı seçilmedi"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "~/.ssh/id_rsa"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "~/.ssh/id_rsa"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "未選取 id_rsa 金鑰"
}
}
}
},
"WeT-3V-zwk.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Paste and Match Style\"; ObjectID = \"WeT-3V-zwk\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "لصق ومطابقة النمط"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vložit a použít styl"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Einsetzen und Stil anpassen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Paste and Match Style"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pegar con el mismo estilo"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Coller et appliquer le style"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הדבק והתאם לסגנון"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पेस्ट और मैच स्टाइल"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Incolla e abbina lo stile"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ペーストしてスタイルを合わせる"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "붙여넣고 스타일 일치시킴"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Plak en pas stijl aan"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Colar e combinar estilo"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Colar e igualar o estilo"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вставить в соответствии стилю"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yapıştır ve Stili Eşleştir"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вставити з відповідним стилем"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "粘贴并匹配样式"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "貼上並符合樣式"
}
}
}
},
"WHt-T4-l9c.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Hide/Show Note List\"; ObjectID = \"WHt-T4-l9c\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "إخفاء / إظهار قائمة الملاحظات"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Skrýt/zobrazit seznam poznámek"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notizliste an/ausblenden"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Hide/Show Note List"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ocultar/mostrar notas"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Masquer/afficher la liste de notes"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הסתר/הצג רשימת פתקים"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नोट सूची छिपाएँ/दिखाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nascondi/mostra l'elenco delle note"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ノート一覧の表示/非表示"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "노트 목록 숨기기/보이기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verbergen/tonen notitielijst"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ocultar/mostar listar de notas"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ocultar/mostrar lista de notas"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Спрятать/показать список заметок"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Not Listesini Gizle/Göster"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Приховати/показати нотатки"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "隐藏/显示笔记列表"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "隱藏/顯示筆記清單"
}
}
}
},
"wpr-3q-Mcd.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Help\"; ObjectID = \"wpr-3q-Mcd\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "مساعدة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nápověda"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hilfe"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Help"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ayuda"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aide"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "עזרה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "सहायता"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aiuto"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ヘルプ"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "도움말"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Help"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ajuda"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ajuda"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Помощь"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yardım"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Допомога"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "帮助"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "輔助說明"
}
}
}
},
"Ws8-ql-C52.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Arrange note list above editor\"; ObjectID = \"Ws8-ql-C52\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "وضع قائمة الملاحظات فوق المحرر"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Umístit seznam poznámek nad editor"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Die Notizenliste über dem Editor anzeigen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Arrange note list above editor"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Colocar la lista de notas encima del editor"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Afficher la liste des notes au-dessus de l'éditeur"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "להציג את רשימת ההערות מעל העורך"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "संपादक के ऊपर नोट्स की सूची रखें।"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Posizionare l'elenco delle note sopra l'editor"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "エディタの上にメモの一覧を表示する"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "편집기 위에 메모 목록 배치하기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "De lijst met notities boven de editor plaatsen"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Exibir a lista de notas acima do editor"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Colocar a lista de notas acima do editor"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Расположить список заметок над редактором"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Not listesini düzenleyicinin üstüne yerleştir"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Розмістити список нотаток над редактором"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "在编辑器上方显示备忘录列表"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "將備忘錄清單置於編輯器上方"
}
}
}
},
"WsG-JA-VQd.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Passphrase:\"; ObjectID = \"WsG-JA-VQd\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Passphrase:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Přístupová fráze:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Passphrase:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Passphrase:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Passphrase:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Passphrase:"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Passphrase:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पासफ्रेज:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Passphrase:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Passphrase:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Passphrase:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Passphrase:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Frase secreta:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Passphrase:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Парольная фраза:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Parola"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Passphrase:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "Passphrase:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "通關密語:"
}
}
}
},
"wW6-4n-sve.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Auto Rename By Title\"; ObjectID = \"wW6-4n-sve\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "إعادة تسمية تلقائية بالعنوان"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Podle nadpisu"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Auto rename by title"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Auto Rename By Title"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renombrar automáticamente por título"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Selon le titre"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "תן שם לפי כותרת"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "शीर्षक द्वारा स्वतः नाम बदलें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rinomina automaticamente per titolo"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "タイトルをファイル名に自動反映"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "제목으로 자동 이름 바꾸기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Automatisch hernoemen op titel"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renomear automaticamente por título"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renomear automaticamente por título"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "По заголовку"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Başlığa Göre Otomatik Yeniden Adlandırma"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Автоматичне перейменування за назвою"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "按标题自动重命名"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "依標題自動重新命名"
}
}
}
},
"wxM-bE-TE9.label" : {
"comment" : "Class = \"NSTabViewItem\"; label = \"Git\"; ObjectID = \"wxM-bE-TE9\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Git"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "गिट"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
}
}
},
"X3S-sG-ykW.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Quote\"; ObjectID = \"X3S-sG-ykW\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "اقتبس"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Citát"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zitat"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Quote"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Citar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Citation"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "ציטוט"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "उद्धरण"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Citazione"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "引用符"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "인용문"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Quote"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aspas"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Citação"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Цитата"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Alıntı"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Цитата"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "引用"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "引用"
}
}
}
},
"x3v-GG-iWU.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Copy\"; ObjectID = \"x3v-GG-iWU\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "نسخ"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kopírovat"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kopieren"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Copy"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copiar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copier"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "העתק"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कॉपी करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copia"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "コピー"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "복사"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kopieer"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copiar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copiar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Копировать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kopyala"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Скопіювати"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "拷贝"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "複製"
}
}
}
},
"X76-X8-PbG.title" : {
"comment" : "Class = \"NSViewController\"; title = \"Publish\"; ObjectID = \"X76-X8-PbG\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "ينشر"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zveřejnit"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Veröffentlichen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Publish"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Publicar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Publier"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "לְפַרְסֵם"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "प्रकाशित करें:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pubblicare"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Publish"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "게시"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Publiceren"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Publicar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Publicar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Публикация"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yayımla"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Опублікувати"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "发布"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "發布"
}
}
}
},
"XBB-Sr-T1D.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Rename\"; ObjectID = \"XBB-Sr-T1D\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "اعادة تسمية"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Přejmenovat"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Umbenennen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Rename"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renombrar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renommer"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "שנה שם"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नाम बदलें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rinomina"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "名前を変更"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "이름 변경"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hernoem"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renomear"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renomear"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Переименовать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yeniden isimlendirmek"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перейменувати"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "重命名"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "重新命名"
}
}
}
},
"xeP-Zg-vmO.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Bold:\"; ObjectID = \"xeP-Zg-vmO\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fett:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Bold:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Negrita:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Gras :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "बोल्ड:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Grassetto:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Жирный:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kalın:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Жирний:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "粗体:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "粗體:"
}
}
}
},
"XEU-Ia-4j2.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Reset\"; ObjectID = \"XEU-Ia-4j2\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "إعادة ضبط"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Resetovat"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zurücksetzen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Reset"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Reiniciar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Réinitialiser"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "אִתחוּל"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "रीसेट करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ripristina"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "リセット"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "초기화"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Resetten"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Resetar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Redefinir"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сбросить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sıfırla"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Скинути"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "重置"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "重設"
}
}
}
},
"xfW-7n-cIw.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Link\"; ObjectID = \"xfW-7n-cIw\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "رابط"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Odkaz"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Link"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Link"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Enlace"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lien"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "קישור"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "लिंक"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Link"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "リンク"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "링크"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Link"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Link"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ligação"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ссылка"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Link"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Посилання"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "链接"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "連結"
}
}
}
},
"xjf-5G-e5Q.title" : {
"comment" : "Class = \"NSMenu\"; title = \"Show in Sidebar\"; ObjectID = \"xjf-5G-e5Q\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "إظهار في الشريط الجانبي"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zobrazit v bočním panelu"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "In der Seitenleiste anzeigen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Show in Sidebar"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar en la barra lateral"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Afficher dans la barre latérale"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הצג בסרגל צד"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "साइडबार में दिखाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostra nella barra laterale"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "サイトバーに表示"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "사이드 바에 표시"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Toon in zijbalk"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar menu lateral"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar na barra lateral"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показывать в сайдбаре"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kenar Çubuğunda Göster"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показувати на бічній панелі"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "在侧边栏中显示"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "顯示於側邊欄"
}
}
}
},
"xJQ-ch-Xlp.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Preview Font Size:\"; ObjectID = \"xJQ-ch-Xlp\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "معاينة حجم الخط:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Veilkost písma v náhledu:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vorschauschrift:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Preview Font Size:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tamaño de fuente de la previsualización:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Taille de l'aperçu :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "גודל גופן תצוגה:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "फ़ॉन्ट आकार पूर्वावलोकन:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dimensione carattere:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "プレビューフォントサイズ:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "서체 크기 미리보기:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Voorvertoning Lettertypegrootte:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pré-visualização da fonte do texto:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pré-visualizar tamanho do tipo de letra:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Шрифт предпросмотра:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Önizleme Yazı Boyutu:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Шрифт прев'ю:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "预览字号:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "預覽字體大小:"
}
}
}
},
"xPh-BC-Xxl.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"History\"; ObjectID = \"xPh-BC-Xxl\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تاريخ"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Historie"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Die geschichte"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "History"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Historia"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Historique"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "היסטוריה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "इतिहास"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cronologia"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "履歴"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "변경 이력"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Geschiedenis"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Histórico"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Histórico"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "История"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tarih"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Історія"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "笔记历史版本"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "歷程記錄"
}
}
}
},
"xPz-yo-VwM.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Notes\"; ObjectID = \"xPz-yo-VwM\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "ملاحظات"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Poznámky"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notizen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Notes"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notas"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remarques"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "פתקים"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नोट"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Note"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "すべて"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "모든 노트"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notes"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notas"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "notas"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заметки"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notlar"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Нотатки"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "笔记"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "筆記"
}
}
}
},
"xrE-MZ-jX0.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Speech\"; ObjectID = \"xrE-MZ-jX0\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "كلام"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Řeč"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sprachausgabe"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Speech"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Habla"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Langage"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הקראה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "भाषण"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Voce"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "スピーチ"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "말하기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Spraak"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fala"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ditar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Диктовка"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Konuşma"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Диктування"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "语音"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "語音"
}
}
}
},
"xSO-lW-k8f.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Reveal in Finder\"; ObjectID = \"xSO-lW-k8f\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "فتح المجلد"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zobrazit ve Finderu"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "In Finder anzeigen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Reveal in Finder"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar en el Finder"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Localiser dans le Finder"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הצג ב-Finder"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "Finder में दिखाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostra nel Finder"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Finderに表示"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Finder에서 보기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Onthul in Finder"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Revelar no Finder"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Realçar no Finder"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показать в Finder"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Finder'da göster"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показати в Finder"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "在访达中显示"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "顯示於 Finder"
}
}
}
},
"xWi-IK-gJS.placeholderString" : {
"comment" : "Class = \"NSSecureTextFieldCell\"; placeholderString = \"optional\"; ObjectID = \"xWi-IK-gJS\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "اختياري"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "nepovinné"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "optional"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "optional"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "opcional"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "optionnelle"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "אופציונאלי"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "वैकल्पिक"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "opzionale"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "オプション"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "선택 과목"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "optioneel"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Opcional"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "opcional"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "необязательный"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "isteğe bağlı"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "необов'язково"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "可选的"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "選填"
}
}
}
},
"xX0-9b-KDq.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Code block live highlighting\"; ObjectID = \"xX0-9b-KDq\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تسليط الضوء على كتلة التعليمات البرمجية (إعادة تشغيل التطبيق مطلوب)"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Živé zvýraznění u bloku kódu"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Syntax automatisch hervorheben"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Code block live highlighting"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Resaltado sintáctico de código"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Surbrillance de code"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הדגש בלוקי קוד בזמן אמת (דורש אתחול)"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कोड ब्लॉक लाइव हाइलाइटिंग"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Evidenzia il blocco di codice"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "コードブロックの色付け"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "코드 영역 실시간 강조"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Codeblok live markering"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Destacar em tempo real o bloco de código"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Realçar bloco de código"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Живая подсветка кода"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kod bloğu canlı vurgulama"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Миттєве підсвічування коду"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "代码块实时高亮显示"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "程式碼區塊即時突顯"
}
}
}
},
"xxB-ic-LFu.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"None\"; ObjectID = \"xxB-ic-LFu\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "بلا"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Žádné"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "None"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "None"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ninguno"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aucun"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "ללא"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कोई भी नहीं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nessuno"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "なし"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "없음"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Geen"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nada"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nenhum"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Не использовать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hiçbiri"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Немає"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "无"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "無"
}
}
}
},
"xyK-fE-4CD.placeholderString" : {
"comment" : "Class = \"NSSecureTextFieldCell\"; placeholderString = \"passphrase\"; ObjectID = \"xyK-fE-4CD\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "passphrase"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "přístupová fráze"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "passphrase"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "passphrase"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "passphrase"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "passphrase"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "passphrase"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पासफ्रेज"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "passphrase"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "passphrase"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "passphrase"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "passphrase"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "frase secreta"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "passphrase"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "passphrase"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Parola"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "passphrase"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "passphrase"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "通關密語"
}
}
}
},
"Xz5-n4-O0W.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Find…\"; ObjectID = \"Xz5-n4-O0W\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "ابحث ..."
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hledat…"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Suchen …"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Find…"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Buscar…"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rechercher…"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "חפש..."
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "खोजे..."
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Trova…"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "検索…"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "찾기..."
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zoeken…"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Procurar..."
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pesquisar..."
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Найти…"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bul…"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Знайти..."
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "查找…"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "尋找…"
}
}
}
},
"y4W-TV-iZ3.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Toggle Container\"; ObjectID = \"y4W-TV-iZ3\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Toggle Container"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zapnout/vypnout kontejner"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Toggle Container"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Toggle Container"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Toggle Container"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Toggle Container"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Toggle Container"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "टॉगल कंटेनर"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Toggle Container"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Toggle Container"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Toggle Container"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Toggle Container"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Alternar Container"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Toggle Container"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Изменить контейнер"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Konteyneri Aç/Kapat"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Toggle Container"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "切换容器"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "切換容器"
}
}
}
},
"y5T-sb-gw4.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Autoname by Title (30s)\"; ObjectID = \"y5T-sb-gw4\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "التسمية التلقائية حسب العنوان"
}
},
"cs" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Automatické pojmenování podle názvu"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Automatische Benennung nach Titel"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Autoname by Title (30s)"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Asignación automática de nombres por título"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dénomination automatique par titre"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "מתן שמות אוטומטית לפי כותרת"
}
},
"hi" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "शीर्षक के अनुसार स्वचालित नामकरण"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Denominazione automatica per titolo"
}
},
"ja" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "タイトルによる自動命名"
}
},
"ko" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "제목별 자동 이름 지정"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Automatische naamgeving op titel"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Nomeação automática por título"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Nomeação automática por título"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Автоименование по заголовку (30с)"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Başlığa Göre Otomatik Adlandırma"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Автоіменування за заголовком (30c)"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "按标题自动命名"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "依標題自動命名 (30s)"
}
}
}
},
"y7T-Rc-etT.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Name\"; ObjectID = \"y7T-Rc-etT\"; Note = \"#bc-ignore!\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "jméno"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Name"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नाम"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "İsim"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Name"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
}
},
"shouldTranslate" : false
},
"ybG-au-Sf4.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Git repository\"; ObjectID = \"ybG-au-Sf4\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git repository"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git repozitář"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git repository"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Git repository"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git repository"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git repository"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git repository"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "गिट रिपोजिटरी"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git repository"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git repository"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git repository"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git repository"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Repositório Git"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git repository"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git репозиторий"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git deposu"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git repository"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git repository"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git 儲存庫"
}
}
}
},
"YEy-JH-Tfz.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Find and Replace…\"; ObjectID = \"YEy-JH-Tfz\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "بحث واستبدال ..."
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hledat a nahradit…"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Suchen und ersetzen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Find and Replace…"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Buscar y reemplazar…"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rechercher et remplacer…"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "מצא והחלף..."
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "खोजे और बदलें…"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Trova e Sostituisci…"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "検索と置換…"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "찾기 및 대치..."
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zoeken en Vervangen…"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Procurar e substituir..."
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pesquisar e Substituir"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Найти и заменить…"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bul ve Değiştir…"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Знайти та замінити..."
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "查找和替换…"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "尋找與取代…"
}
}
}
},
"yMK-aK-OV2.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Move Selected Lines Up\"; ObjectID = \"yMK-aK-OV2\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ausgewählte Zeilen nach oben verschieben"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Move Selected Lines Up"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mover líneas seleccionadas hacia arriba"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Déplacer les lignes sélectionnées vers le haut"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "चुनी हुई पंक्तियों को ऊपर ले जाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sposta righe selezionate verso l'alto"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Переместить выбранные строки вверх"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Seçili Satırları Yukarı Taşı"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перемістити вибрані рядки вгору"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "选中行向上移动"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "將選取的行上移"
}
}
}
},
"yMX-hz-B8Y.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"__\"; ObjectID = \"yMX-hz-B8Y\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "__"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "__"
}
}
},
"shouldTranslate" : false
},
"yNE-Yn-AWj.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Quick note:\"; ObjectID = \"yNE-Yn-AWj\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "ملاحظة سريعة:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rychlá poznámka:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kurze Anmerkung:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Quick note:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nota rápida:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Note rapide:"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הערה מהירה:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "त्वरित नोट:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nota veloce:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "クイックノート:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "빠른 메모:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Snelle notitie:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nota rápida:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nota rápida:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Быстрая заметка:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kısa not:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Швидка нотатка:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "速记:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "快速筆記:"
}
}
}
},
"Ynk-f8-cLZ.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Start Speaking\"; ObjectID = \"Ynk-f8-cLZ\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "بدء التحدث"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Spustit předčítání"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sprachausgabe starten"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Start Speaking"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Iniciar locución"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Démarrer la diction"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "התחל להקריא"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "बोलना शुरू करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Avvia Lettura"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "読み上げを開始"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "말하기 시작"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Start met Praten"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Começar a falar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Começar Ditado"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Начать диктовку"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Konuşmaya Başla"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Почати диктування"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "开始朗读"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "開始朗讀"
}
}
}
},
"You-zo-rbl.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Pin/Unpin\"; ObjectID = \"You-zo-rbl\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "تثبيت / فك التثبيت"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Připnout/odepnout"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fixieren/Loslösen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Pin/Unpin"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Anclar/desanclar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Épingler/Désépingler"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הצמד/בטל הצמדה"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पिन/अनपिन"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fissa/Sblocca"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "メモをピンで固定/ピン固定の解除"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "고정/고정 해제"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pin/VerwijderPin"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fixar/Desafixar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fixar/soltar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Закрепить/открепить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sabitle/Sabitlemeyi kaldır"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Закріпити/відкріпити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "置顶/取消置顶"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "釘選/取消釘選"
}
}
}
},
"ypO-g0-1Xo.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Automatically insert closing braces and close quotes\"; ObjectID = \"ypO-g0-1Xo\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "إدراج تلقائي لغلق الاقواس والاقتباسات"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Automaticky zavírat závorky a uvozovky"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Klammern und Anführungszeichen automatisch einfügen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Automatically insert closing braces and close quotes"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cerrar corchetes y comillas automáticamente"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Parenthèses et guillemets fermants automatiques"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הכנס באופן אוטומטי סוגריים ומרכאות סוגרים"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "स्वचालित रूप से समापन ब्रेसिज़ और समापन उद्धरण सम्मिलित करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aggiungi in automatico parentesi e virgolette di chiusura"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "自動的に閉じ括弧や右引用符を挿入"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "자동으로 괄호와 인용 닫기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Automatisch invoegen sluithaken en sluit aanhalingstekens "
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fechar automaticamente aspas"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fechar automáticamente parêntesis e aspas"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Автоматически закрывать скобки и кавычки"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Otomatik olarak kapanış parantezlerini ve kapanış tırnak işaretlerini ekle"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Автоматично закривати дужки та лапки"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "自动补全右括号和右引号"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "自動插入結尾括號與引號"
}
}
}
},
"yVt-tz-tMy.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Username:\"; ObjectID = \"yVt-tz-tMy\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "اسم المستخدم:"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Uživatelské jméno:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Benutzername:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Username:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nombre de usuario:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nom d'utilisateur:"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "שם משתמש:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "उपयोगकर्ता नाम:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nome utente:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ユーザー名:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "사용자 이름:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Gebruikersnaam:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nome de usuário: "
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nome de usuário:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Имя:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kullanıcı Adı:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ім'я користувача:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "用户名:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "使用者名稱:"
}
}
}
},
"yx6-SW-3vn.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Image or File\"; ObjectID = \"yx6-SW-3vn\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "صورة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Obrázek nebo soubor"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bild"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Image or File"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Imagen"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Image ou fichier"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "תמונה או קובץ"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "छवि या फ़ाइल"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Immagine o file"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "画像またはファイル"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "이미지"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Afbeelding of bestand"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Imagem ou arquivo"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Imagem ou ficheiro"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Изображение или файл"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Resim veya Dosya"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Зображення або файл"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "图像"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "圖片或檔案"
}
}
}
},
"z6F-FW-3nz.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Show Substitutions\"; ObjectID = \"z6F-FW-3nz\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "مشاهدة التبديلات"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zobrazit záměny"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ersetzungen einblenden"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Show Substitutions"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar substituciones"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Afficher les Substitutions"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הצג החלפות"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "प्रतिस्थापन दिखाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostra Sostituzioni"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "自動置換を表示"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "대체 보기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Toon Vervangingen"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar substituições"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar Substituições"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показать замены"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yerine Geçenleri Göster"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показати заміни"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "显示替换"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "顯示替代"
}
}
}
},
"zcY-e5-gKs.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Open in External Editor:\"; ObjectID = \"zcY-e5-gKs\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "فتح في محرر خارجي"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Otevřít v externím editoru:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "In externem Editor öffnen:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Open in External Editor:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Abrir en editor externo:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ouvrir dans un éditeur externe :"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "פתח בעורך חיצוני:"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "बाहरी संपादक में खोलें:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Apri in un editor esterno:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "外部エディタで開く:"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "외부 편집기에서 열기:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Open in externe editor:"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Abrir em editor externo:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Abrir no editor externo:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Внешний редактор:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Harici Düzenleyicide Aç:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Відкрити в редакторі:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "在外部编辑器中打开:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "在外部編輯器開啟:"
}
}
}
},
"zd2-Rs-DPm.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Force Delete\"; ObjectID = \"zd2-Rs-DPm\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "حذف اجباري"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vynutit smazání"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Force Delete"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Force Delete"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Forzar eliminación"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Forcer la suppression"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "מחק מיידית"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "बलपूर्वक हटाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Forza Cancellazione"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "強制的に削除"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "강제 삭제"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Forceer verwijderen"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Forçar deletar"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Forçar Apagar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Принудительное удаление"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zorla Sil"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Примусово видалити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "强制删除"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "強制刪除"
}
}
}
},
"ZDl-8b-mam.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"10\"; ObjectID = \"ZDl-8b-mam\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "3"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "10"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "3"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "10"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "3"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "3"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "3"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "10"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "3"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "3"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "3"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "3"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "10"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "3"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "10"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "10"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "3"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "3"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "10"
}
}
}
},
"Ze0-SZ-STw.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Back up manually\"; ObjectID = \"Ze0-SZ-STw\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "قم بعمل نسخة احتياطية يدويًا"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zálohovat ručně"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Manuell sichern"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Back up manually"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copia de seguridad manual"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sauvegarder manuellement"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "גבה באופן ידני"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "मैन्युअल रूप से बैकअप लें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Esegui il backup manualmente"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "手動バックアップ"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "수동으로 백업"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Back-up handmatig"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Backup manualmente"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cópia de segurança manual"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Резервные копии вручную"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Manuel olarak yedekleyin"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вручну"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "手动备份"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "手動備份"
}
}
}
},
"ZqK-gu-KdQ.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Note auto selection when body text matched\"; ObjectID = \"ZqK-gu-KdQ\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "لاحظ التحديد التلقائي عند مطابقة النص الأساسي"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Automaticky vybrat poznámku při shodě textu"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notiz automatisch wählen, wenn der Text übereinstimmt"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Note auto selection when body text matched"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Seleccionar la nota automáticamente cuando el texto coincida"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sélec. auto de note lorsqu'un corps correspond"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "בחירה אוטומטית בפתקים כשגוף הטקסט תואם"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "मुख्य पाठ मिलने पर नोट का स्वतः चयन करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Seleziona la nota che contiente nel corpo il testo cercato"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "検索でヒットしたノートを自動で選択する"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "본문 텍스트 발견 시 노트 자동 선택"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Selecteer notitie automatisch als de hoofdtekst overeenkomt"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Seleção automática de notas quando o texto do corpo coincide"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Auto-seleccionar nota quando o texto corresponde"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Выбирать заметку, если тело соответствует запросу"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Gövde metni eşleştiğinde otomatik seçimi not edin"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Автовибір нотатки при збігу тексту"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "正文文本匹配时自动选择笔记"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "內文符合時自動選取筆記"
}
}
}
},
"zRJ-Z2-Lsa.title" : {
"comment" : "Class = \"NSMenu\"; title = \"Move Item\"; ObjectID = \"zRJ-Z2-Lsa\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Element verschieben"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Move Item"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mover elemento"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Déplacer l'élément"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "आइटम हटाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sposta elemento"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Переместить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Öğeyi Taşı"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перемістити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "移动项目"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "移動項目"
}
}
}
},
"Zzw-01-JH7.title" : {
"comment" : "Class = \"NSButtonCell\"; title = \"Show notes in \\\"Notes\\\" and \\\"Todo\\\" lists\"; ObjectID = \"Zzw-01-JH7\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "إظهار الملاحظات في قائمة \"ملاحظات\" و \"قائمة المهام\""
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zobrazit poznámky v seznamech „Poznámky“ a „Úkoly“"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notizen in den Listen \"Notizen\" und \"Todo\" anzeigen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Show notes in \"Notes\" and \"Todo\" lists"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostras las notas en las listas \"Notas\" y \"Pendientes\""
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Voir les notes dans \"Notes\" et \"Tâches\""
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "הצג פתקים ברשימות ״פתקים״ ו-״מטלות״"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "\"नोट्स\" और \"टुडू\" सूचियों में नोट्स दिखाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostra le note negli elenchi \"Note\" e \"Da Fare\""
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "\"すべて\" と \"タスク\" にノートを表示"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "\"모든 노트\"와 \"할 일\"에 있는 노트 보기"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Toon notities in \"Notes\" en \"Todo\" lijsten"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar notas em \\\"Notes\\\" and \\\"Todo\\\" listas"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar notas nas listas \"Notas\" e \"Tarefas\""
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показывать заметки в общих"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notları “Notlar” ve “Yapılacaklar” listelerinde gösterme"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показувати у \"Нотатках\" і \"Завданнях\""
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "在\"笔记\"和\"待办事项\"列表中显示备注"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "在「筆記」與「待辦事項」清單中顯示筆記"
}
}
}
}
},
"version" : "1.0"
}
================================================
FILE: FSNotes Info (Notarized).plist
================================================
ATSApplicationFontsPath
.
CFBundleDevelopmentRegion
$(DEVELOPMENT_LANGUAGE)
CFBundleDisplayName
FSNotes
CFBundleDocumentTypes
CFBundleTypeExtensions
etp
CFBundleTypeIconFile
EncryptedTextPack
CFBundleTypeMIMETypes
CFBundleTypeName
Encrypted Text Pack
CFBundleTypeRole
Editor
LSHandlerRank
Owner
LSItemContentTypes
es.fsnot.etp.package
LSTypeIsPackage
0
NSDocumentClass
CFBundleTypeExtensions
textbundle
CFBundleTypeIconFile
TextBundle
CFBundleTypeName
TextBundle
CFBundleTypeRole
Editor
LSHandlerRank
Default
LSItemContentTypes
org.textbundle.package
LSTypeIsPackage
1
NSDocumentClass
CFBundleTypeExtensions
md
markdown
CFBundleTypeIconFile
Markdown
CFBundleTypeName
Markdown
CFBundleTypeRole
Editor
LSHandlerRank
Default
LSItemContentTypes
net.daringfireball.markdown
CFBundleTypeExtensions
rtf
CFBundleTypeIconFile
RTF
CFBundleTypeName
Rich Text
CFBundleTypeRole
Editor
LSHandlerRank
Alternate
LSItemContentTypes
public.rtf
CFBundleTypeExtensions
txt
plain-text
CFBundleTypeIconFile
Text
CFBundleTypeName
Text
CFBundleTypeRole
Editor
LSHandlerRank
Alternate
LSItemContentTypes
public.plain-text
CFBundleExecutable
$(EXECUTABLE_NAME)
CFBundleIdentifier
$(PRODUCT_BUNDLE_IDENTIFIER)
CFBundleInfoDictionaryVersion
6.0
CFBundleName
FSNotes
CFBundlePackageType
APPL
CFBundleShortVersionString
$(MARKETING_VERSION)
CFBundleURLTypes
CFBundleTypeRole
Viewer
CFBundleURLIconFile
makeNote
CFBundleURLName
co.fluder.fsnotes
CFBundleURLSchemes
fsnotes
CFBundleTypeRole
Viewer
CFBundleURLIconFile
makeNote
CFBundleURLName
co.fluder.fsnotes
CFBundleURLSchemes
nv
CFBundleTypeRole
Viewer
CFBundleURLIconFile
makeNote
CFBundleURLName
co.fluder.fsnotes
CFBundleURLSchemes
nvalt
CFBundleVersion
$(CURRENT_PROJECT_VERSION)
LSApplicationCategoryType
public.app-category.productivity
LSMinimumSystemVersion
$(MACOSX_DEPLOYMENT_TARGET)
LSUIElement
NSAppTransportSecurity
NSAllowsArbitraryLoads
NSHumanReadableCopyright
Copyright © 2017-2022 Oleksandr Hlushchenko. All rights reserved.
NSMainStoryboardFile
Main
NSPrincipalClass
NSApplication
NSUbiquitousContainers
iCloud.co.fluder.fsnotes
NSUbiquitousContainerIsDocumentScopePublic
NSUbiquitousContainerName
FSNotes
NSUbiquitousContainerSupportedFolderLevels
One
NSUserActivityTypes
es.fsnot.handoff-open-note
UTExportedTypeDeclarations
UTTypeConformsTo
public.data
UTTypeDescription
Encrypted Text Pack
UTTypeIconFile
EncryptedTextPack
UTTypeIdentifier
es.fsnot.etp.package
UTTypeReferenceURL
https://fsnot.es
UTTypeTagSpecification
public.filename-extension
etp
public.mime-type
UTTypeConformsTo
com.apple.package
UTTypeDescription
TextBundle
UTTypeIconFile
TextBundle
UTTypeIdentifier
org.textbundle.package
UTTypeReferenceURL
http://www.textbundle.org
UTTypeTagSpecification
public.filename-extension
textbundle
UTTypeConformsTo
public.plain-text
UTTypeDescription
Markdown
UTTypeIconFile
Markdown
UTTypeIdentifier
net.daringfireball.markdown
UTTypeTagSpecification
public.filename-extension
md
markdown
public.mime-type
text/markdown
UTTypeConformsTo
public.text
UTTypeDescription
Plain Text
UTTypeIconFile
Text
UTTypeIdentifier
public.plain-text
UTTypeTagSpecification
public.filename-extension
txt
public.mime-type
text/plain
UTTypeConformsTo
public.text
UTTypeDescription
Rich Text
UTTypeIconFile
RTF
UTTypeIdentifier
public.rtf
UTTypeTagSpecification
public.filename-extension
rtf
public.mime-type
text/rtf
================================================
FILE: FSNotes iOS/.bartycrouch.toml
================================================
[update]
tasks = ["interfaces", "code", "transform", "normalize"]
[update.interfaces]
paths = ["."]
defaultToBase = true
ignoreEmptyStrings = false
unstripped = false
[update.code]
codePaths = ["."]
localizablePaths = ["."]
defaultToKeys = true
additive = false
unstripped = false
plistArguments = true
[update.transform]
codePaths = ["."]
localizablePaths = ["."]
transformer = "foundation"
supportedLanguageEnumPath = "."
typeName = "BartyCrouch"
translateMethodName = "translate"
[update.normalize]
paths = ["."]
sourceLocale = "en"
harmonizeWithSource = true
sortByKeys = true
[lint]
paths = ["."]
duplicateKeys = false
emptyValues = true
================================================
FILE: FSNotes iOS/AppDelegate.swift
================================================
//
// AppDelegate.swift
// FSNotes iOS
//
// Created by Oleksandr Glushchenko on 1/29/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
//
// AppDelegate.swift
// FSNotes iOS
//
// Created by Oleksandr Glushchenko on 1/29/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import UIKit
import CoreData
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
public static var gitVC = [String: GitViewController]()
public static var gitProgress: GitProgress?
// MARK: Static Properties
static let applicationShortcutUserInfoIconKey = "applicationShortcutUserInfoIconKey"
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Setup dynamic shortcuts
let newDocument = NSLocalizedString("New Note", comment: "")
let shortcutNew = UIMutableApplicationShortcutItem(
type: ShortcutIdentifier.makeNew.type,
localizedTitle: newDocument,
localizedSubtitle: "",
icon: UIApplicationShortcutIcon(type: .compose),
userInfo: nil
)
let saveClipboard = NSLocalizedString("Save Clipboard", comment: "")
let shortcutNewClipboard = UIMutableApplicationShortcutItem(
type: ShortcutIdentifier.clipboard.type,
localizedTitle: saveClipboard,
localizedSubtitle: "",
icon: UIApplicationShortcutIcon(type: .add),
userInfo: nil
)
let search = NSLocalizedString("Search or Create", comment: "")
let shortcutSearch = UIMutableApplicationShortcutItem(
type: ShortcutIdentifier.search.type,
localizedTitle: search,
localizedSubtitle: "",
icon: UIApplicationShortcutIcon(type: .search),
userInfo: nil
)
application.shortcutItems = [shortcutNew, shortcutNewClipboard, shortcutSearch]
return true
}
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
// Called when the user discards a scene session.
}
func applicationWillTerminate(_ application: UIApplication) {
UserDefaultsManagement.crashedLastTime = false
let temp = NSTemporaryDirectory()
let encryption = URL(fileURLWithPath: temp).appendingPathComponent("Encryption")
try? FileManager.default.removeItem(at: encryption)
let webkitPreview = URL(fileURLWithPath: temp).appendingPathComponent("wkPreview")
try? FileManager.default.removeItem(at: webkitPreview)
let imagesPreview = URL(fileURLWithPath: temp).appendingPathComponent("ThumbnailsBig")
try? FileManager.default.removeItem(at: imagesPreview)
Storage.shared().saveProjectsCache()
print("Termination end, crash status: \(UserDefaultsManagement.crashedLastTime)")
}
func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
if let iCloudDocumentsURL = FileManager.default.url(forUbiquityContainerIdentifier: nil)?.appendingPathComponent("Documents").standardized,
!FileManager.default.fileExists(atPath: iCloudDocumentsURL.path, isDirectory: nil) {
do {
try FileManager.default.createDirectory(at: iCloudDocumentsURL, withIntermediateDirectories: true, attributes: nil)
} catch {
print("Home directory creation: \(error)")
}
}
return true
}
// MARK: - Static Helper Methods
public static func getGitVC(for project: Project) -> GitViewController {
if let gitVC = AppDelegate.gitVC[project.settingsKey] {
return gitVC
}
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let gvc = storyBoard.instantiateViewController(withIdentifier: "gitSettingsViewController") as! GitViewController
gvc.setProject(project)
AppDelegate.gitVC[project.settingsKey] = gvc
return gvc
}
public static func getGitVCOptional(for project: Project) -> GitViewController? {
if let gitVC = AppDelegate.gitVC[project.settingsKey] {
return gitVC
}
return nil
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Colors/Contents.json
================================================
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Colors/fsColor.colorset/Contents.json
================================================
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.850",
"green" : "0.600",
"red" : "0.080"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.850",
"green" : "0.600",
"red" : "0.080"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Contents.json
================================================
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Editor/Contents.json
================================================
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Editor/checkbox.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "checkbox.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "checkbox_white.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "checkbox@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "checkbox_white@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "checkbox@3x.png",
"idiom" : "universal",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "checkbox_white@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Editor/checkbox_empty.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "checkbox_empty.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "checkbox_empty_white 1.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "checkbox_empty@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "checkbox_empty_white@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "checkbox_empty@3x.png",
"idiom" : "universal",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "checkbox_empty_white@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Icons/AppIconClassic-2025.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "classic.png",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Icons/AppIconModern.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "classic-iOS-Default-1024x1024@1x.png",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Icons/AppIconNy-2026.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "ny-2026-iOS-Default-1024x1024@1x.png",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Icons/Contents.json
================================================
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/LaunchScreenImage.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "icon-1024-1024-tint.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "app-icon-dylanseegerDarkFull.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "icon-1024-1024-tint 1.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "app-icon-dylanseegerDarkFull 1.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "icon-1024-1024-tint 2.png",
"idiom" : "universal",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "app-icon-dylanseegerDarkFull 2.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Sidebar/Contents.json
================================================
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Sidebar/sidebar_archive.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "Archive-76.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Archive-76@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Archive-83.5@2x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Sidebar/sidebar_inbox.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "1172241_inbox_letter_mail_mailbox_icon-76.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "1172241_inbox_letter_mail_mailbox_icon-76@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "1172241_inbox_letter_mail_mailbox_icon-83.5@2x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Sidebar/sidebar_notes.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "Notes-76.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Notes-76@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Notes-83.5@2x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Sidebar/sidebar_project.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "folder-77.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "folder-76@2x-1.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "folder-76@2x-1 1.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Sidebar/sidebar_project_encrypted_locked.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "locked@74.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "locked@148.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "locked@222.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Sidebar/sidebar_project_encrypted_unlocked.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "unlocked@74.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "unlocked@148.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "unlocked@222.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Sidebar/sidebar_tag.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "tag-76.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "tag-76@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "tag-76@2x 1.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Sidebar/sidebar_todo.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "t2-76.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "t2-76@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "t2-83.5@2x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Sidebar/sidebar_trash.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "Trash-76.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Trash-76@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Trash-83.5@2x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Sidebar/sidebar_untagged.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "1172268_tag_tags_icon-76.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "1172268_tag_tags_icon-76@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "1172268_tag_tags_icon-83.5@2x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Sidebar Actions/Contents.json
================================================
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Sidebar Actions/gitSettings.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "git-20.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "git-20 1.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "git-20@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "git-20@2x 1.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "git-20@3x.png",
"idiom" : "universal",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "git-20@3x 1.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Toolbar/Contents.json
================================================
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Toolbar/codeBlockAsset.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "codeblock.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "codeblock-1.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "codeblock-2.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Toolbar/numbered_list.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "numbered_list.png",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Toolbar/ordered_list.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "ordered_list.png",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Toolbar/pictureAsset.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "picture@1x.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "picture@1x-white.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "picture@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "picture@2x-white.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "picture@3x.png",
"idiom" : "universal",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "picture@3x-white.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Toolbar/quote.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "quote.png",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Toolbar/redo.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "redo.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "redo@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "redo@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Toolbar/toolbarBold.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "icons8-bold-52-20.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "icons8-bold-52-20@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "icons8-bold-52-20@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Toolbar/toolbarHeader.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "type-h1-icon_1-20.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "type-h1-icon_1-20@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "type-h1-icon_1-20@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Toolbar/toolbarImage.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "icons8-image-96-20.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "icons8-image-96-20@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "icons8-image-96-20@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Toolbar/toolbarIndentLeft.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "right-indent-20.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "right-indent-20@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "right-indent-20@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Toolbar/toolbarIndentRight.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "left-indent-20.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "left-indent-20@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "left-indent-20@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Toolbar/toolbarItalic.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "italic-text-option-interface-symbol-20.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "italic-text-option-interface-symbol-20@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "italic-text-option-interface-symbol-20@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Toolbar/toolbarTag.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "iconfinder_20-blue_fee-label-price-tag_4488787-20.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "iconfinder_20-blue_fee-label-price-tag_4488787-20@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "iconfinder_20-blue_fee-label-price-tag_4488787-20@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Toolbar/toolbarTodo.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "icons8-todo-list-96-20.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "icons8-todo-list-96-20@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "icons8-todo-list-96-20@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Toolbar/toolbarWiki.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "icons8-documents-96-20.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "icons8-documents-96-20@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "icons8-documents-96-20@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Toolbar/undo.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "undo.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "undo@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "undo@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Touch Bar/Contents.json
================================================
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Touch Bar/Image.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "image.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "image@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "image@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Touch Bar/bold.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "bold.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "bold@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "bold@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Touch Bar/codeblock.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "codeblock.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "codeblock 1.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "codeblock 2.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Touch Bar/indent.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "indent.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "indent@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "indent@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Touch Bar/italic.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "italic.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "italic@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "italic@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Touch Bar/tb_link.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "tb_link.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "tb_link 1.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "tb_link 2.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Touch Bar/todo.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "todo.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "todo@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "todo@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/Assets.xcassets/Touch Bar/unindent.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "unindent.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "unindent@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "unindent@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: FSNotes iOS/DatePickerViewController.swift
================================================
//
// DatePickerViewController.swift
// FSNotes iOS
//
// Created by Александр on 01.02.2022.
// Copyright © 2022 Oleksandr Glushchenko. All rights reserved.
//
import Foundation
import UIKit
class DatePickerViewController: UIViewController {
@IBOutlet weak var datePicker: UIDatePicker!
@IBOutlet weak var navigationBar: UINavigationBar!
@IBOutlet weak var bottomSafeView: UIView!
@IBOutlet weak var navItem: UINavigationItem!
public var notes: [Note]?
override func viewDidLoad() {
super.viewDidLoad()
navigationBar.barTintColor = UIColor.sidebar
navigationBar.tintColor = UIColor.mainTheme
navigationBar.backgroundColor = UIColor.sidebar
bottomSafeView.backgroundColor = UIColor.sidebar
if #available(iOS 14.0, *) {
datePicker.preferredDatePickerStyle = .inline
}
if let date = notes?.first?.creationDate {
datePicker.date = date
}
initButtons()
}
@IBAction func saveDate(_ sender: Any) {
guard let notes = self.notes else { return }
for note in notes {
_ = note.setCreationDate(date: datePicker.date)
}
DispatchQueue.main.async {
UIApplication.getVC().notesTable.reloadRows(notes: notes)
}
self.notes = nil
dismiss(animated: true)
}
@IBAction func closeController(_ sender: Any) {
dismiss(animated: true)
}
private func initButtons() {
let leftString = NSLocalizedString("Cancel", comment: "")
navItem.leftBarButtonItem = UIBarButtonItem(title: leftString, style: .plain, target: self, action: #selector(closeController))
let saveBarButton = UIBarButtonItem(title: NSLocalizedString("Update", comment: ""), style: .plain, target: self, action: #selector(saveDate))
navItem.rightBarButtonItem = saveBarButton
}
}
================================================
FILE: FSNotes iOS/EditorViewController+QuickLook.swift
================================================
//
// EditorViewController+QuickLook.swift
// FSNotes iOS
//
// Created by Oleksandr Hlushchenko on 05.05.2024.
// Copyright © 2024 Oleksandr Hlushchenko. All rights reserved.
//
import QuickLook
extension EditorViewController: QLPreviewControllerDataSource {
func numberOfPreviewItems(in controller: QLPreviewController) -> Int {
return 1
}
func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> any QLPreviewItem {
guard let quickLookURL = quickLookURL else {
fatalError("File URL is nil")
}
return quickLookURL as QLPreviewItem
}
func quickLook(url: URL) {
let previewController = QLPreviewController()
previewController.dataSource = self
quickLookURL = url
navigationController?.pushViewController(previewController, animated: true)
}
}
================================================
FILE: FSNotes iOS/EditorViewController+Search.swift
================================================
//
// EditorViewController+Search.swift
// FSNotes
//
// Created by Oleksandr Hlushchenko on 14.01.2026.
// Copyright © 2026 Oleksandr Hlushchenko. All rights reserved.
//
import UIKit
extension EditorViewController {
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
clearHighlights()
guard !searchText.isEmpty else {
updateCounterLabel()
return
}
findRanges(text: searchText)
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
nextResult()
}
func scrollToCurrent() {
guard !searchRanges.isEmpty else { return }
let range = searchRanges[currentSearchIndex]
let layoutManager = editArea.layoutManager
let textContainer = editArea.textContainer
let targetGlyphRange = layoutManager.glyphRange(
forCharacterRange: range,
actualCharacterRange: nil
)
let extendedGlyphRange = NSRange(
location: 0,
length: targetGlyphRange.location + targetGlyphRange.length
)
layoutManager.ensureLayout(forGlyphRange: extendedGlyphRange)
_ = layoutManager.boundingRect(
forGlyphRange: targetGlyphRange,
in: textContainer
)
editArea.selectedRange = range
editArea.scrollRangeToVisible(range)
updateCounterLabel()
}
func nextResult() {
guard !searchRanges.isEmpty else { return }
currentSearchIndex = (currentSearchIndex + 1) % searchRanges.count
highlightAll()
scrollToCurrent()
}
func prevResult() {
guard !searchRanges.isEmpty else { return }
currentSearchIndex = (currentSearchIndex - 1 + searchRanges.count) % searchRanges.count
highlightAll()
scrollToCurrent()
}
func highlightAll() {
guard !searchRanges.isEmpty else { return }
let textStorage = editArea.textStorage
textStorage.beginEditing()
clearHighlights()
originalBackgrounds.removeAll()
for (index, range) in searchRanges.enumerated() {
let color = index == currentSearchIndex
? UIColor.systemOrange.withAlphaComponent(0.6)
: UIColor.systemYellow.withAlphaComponent(0.4)
let currentBg = textStorage.attribute(.backgroundColor, at: range.location, effectiveRange: nil) as? UIColor
originalBackgrounds[range] = currentBg
textStorage.addAttribute(.backgroundColor, value: color, range: range)
}
textStorage.endEditing()
}
func clearHighlights() {
guard !originalBackgrounds.isEmpty else { return }
let textStorage = editArea.textStorage
textStorage.beginEditing()
for (range, originalColor) in originalBackgrounds {
if let color = originalColor {
textStorage.addAttribute(.backgroundColor, value: color, range: range)
} else {
textStorage.removeAttribute(.backgroundColor, range: range)
}
}
textStorage.endEditing()
originalBackgrounds.removeAll()
}
func findRanges(text: String) {
searchRanges.removeAll()
currentSearchIndex = 0
let nsText = editArea.text as NSString
var searchRange = NSRange(location: 0, length: nsText.length)
while true {
let found = nsText.range(
of: text,
options: .caseInsensitive,
range: searchRange
)
if found.location == NSNotFound { break }
searchRanges.append(found)
searchRange = NSRange(
location: found.location + found.length,
length: nsText.length - found.location - found.length
)
}
highlightAll()
if !searchRanges.isEmpty {
scrollToCurrent()
}
updateCounterLabel()
}
func updateCounterLabel() {
guard let counterLabel = counterLabel else { return }
if searchRanges.isEmpty {
counterLabel.text = ""
} else {
counterLabel.text = "\(currentSearchIndex + 1)/\(searchRanges.count)"
}
}
func showSearch() {
guard let note = editArea.note else { return }
if note.previewState {
togglePreview()
}
if searchToolbar == nil {
setupSearchAccessory()
}
keyboardAnchor?.becomeFirstResponder()
searchBar?.becomeFirstResponder()
originalSelectedRange = editArea.selectedRange
}
func hideSearch() {
keyboardAnchor?.resignFirstResponder()
searchBar?.resignFirstResponder()
searchToolbar = nil
searchBar = nil
counterLabel = nil
keyboardAnchor?.removeFromSuperview()
keyboardAnchor = nil
clearHighlights()
if let range = originalSelectedRange {
editArea.selectedRange = range
}
addToolBar(textField: editArea, toolbar: getMarkdownToolbar())
}
@objc func editorSearch() {
if searchBar != nil {
hideSearch()
} else {
showSearch()
}
}
func setupSearchAccessory() {
keyboardAnchor = UITextField()
keyboardAnchor?.isHidden = true
view.addSubview(keyboardAnchor!)
searchBar = UISearchBar()
guard let searchBar = searchBar else { return }
searchBar.delegate = self
searchBar.placeholder = "Find"
searchBar.autocapitalizationType = .none
searchBar.autocorrectionType = .no
searchBar.searchBarStyle = .minimal
searchBar.showsCancelButton = false
if let textField = searchBar.value(forKey: "searchField") as? UITextField {
textField.clearButtonMode = .never
}
searchBar.translatesAutoresizingMaskIntoConstraints = false
counterLabel = UILabel()
guard let counterLabel = counterLabel else { return }
counterLabel.font = UIFont.monospacedSystemFont(ofSize: 13, weight: .regular)
counterLabel.textColor = .secondaryLabel
counterLabel.textAlignment = .center
counterLabel.translatesAutoresizingMaskIntoConstraints = false
counterLabel.setContentHuggingPriority(.required, for: .horizontal)
counterLabel.setContentCompressionResistancePriority(.required, for: .horizontal)
counterLabel.widthAnchor.constraint(equalToConstant: 45).isActive = true
let prevButton = UIButton(type: .system)
prevButton.setImage(UIImage(systemName: "chevron.up"), for: .normal)
prevButton.addTarget(self, action: #selector(prevTap), for: .touchUpInside)
prevButton.widthAnchor.constraint(equalToConstant: 32).isActive = true
let nextButton = UIButton(type: .system)
nextButton.setImage(UIImage(systemName: "chevron.down"), for: .normal)
nextButton.addTarget(self, action: #selector(nextTap), for: .touchUpInside)
nextButton.widthAnchor.constraint(equalToConstant: 32).isActive = true
let closeButton = UIButton(type: .system)
closeButton.setImage(UIImage(systemName: "xmark"), for: .normal)
closeButton.addTarget(self, action: #selector(closeSearch), for: .touchUpInside)
closeButton.widthAnchor.constraint(equalToConstant: 32).isActive = true
let prev = UIBarButtonItem(customView: prevButton)
let next = UIBarButtonItem(customView: nextButton)
let close = UIBarButtonItem(customView: closeButton)
let searchItem = UIBarButtonItem(customView: searchBar)
let counterItem = UIBarButtonItem(customView: counterLabel)
searchToolbar = UIToolbar()
guard let searchToolbar = searchToolbar else { return }
searchToolbar.items = [
searchItem,
counterItem,
prev,
next,
close
]
searchToolbar.sizeToFit()
keyboardAnchor?.inputAccessoryView = searchToolbar
}
@objc func nextTap() {
nextResult()
}
@objc func prevTap() {
prevResult()
}
@objc func closeSearch() {
clearHighlights()
keyboardAnchor?.resignFirstResponder()
searchBar?.resignFirstResponder()
editArea.inputAccessoryView = nil
editArea.reloadInputViews()
searchToolbar = nil
searchBar = nil
counterLabel = nil
keyboardAnchor?.removeFromSuperview()
keyboardAnchor = nil
self.addToolBar(textField: editArea, toolbar: self.getMarkdownToolbar())
}
func openSearchWithText(_ searchText: String) {
showSearch()
self.searchBar?.text = searchText
self.findRanges(text: searchText)
}
}
================================================
FILE: FSNotes iOS/EditorViewController.swift
================================================
//
// EditorViewController.swift
// FSNotes iOS
//
// Created by Oleksandr Glushchenko on 1/31/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import UIKit
import AudioToolbox
import MobileCoreServices
import Photos
import DropDown
import CoreSpotlight
import PhotosUI
class EditorViewController: UIViewController,
UITextViewDelegate,
UIDocumentPickerDelegate,
UIGestureRecognizerDelegate,
PHPickerViewControllerDelegate,
UIImagePickerControllerDelegate,
UINavigationControllerDelegate,
UISearchBarDelegate
{
public var note: Note?
public var quickLookURL: URL?
private var isUndo = false
private let storageQueue = OperationQueue()
var inProgress = false
var change = 0
public var undoBarButton: UIBarButtonItem?
public var redoBarButton: UIBarButtonItem?
@IBOutlet weak var editArea: EditTextView!
var rowUpdaterTimer = Timer()
public var tagsTimer: Timer?
private let dropDown = DropDown()
private var isLandscape: Bool?
private var lastStyle: UIUserInterfaceStyle?
// Search toolbar
var keyboardAnchor: UITextField?
var counterLabel: UILabel?
var searchBar: UISearchBar?
var searchToolbar: UIToolbar?
var searchRanges: [NSRange] = []
var currentSearchIndex: Int = 0
var originalSelectedRange: NSRange?
var originalBackgrounds: [NSRange: UIColor?] = [:]
override func viewDidLoad() {
storageQueue.maxConcurrentOperationCount = 1
storageQueue.qualityOfService = .userInitiated
editArea.textContainerInset = UIEdgeInsets(top: 13, left: 10, bottom: 0, right: 10)
let imageTap = SingleImageTouchDownGestureRecognizer(target: self, action: #selector(imageTapHandler(_:)))
editArea.addGestureRecognizer(imageTap)
let tap = SingleTouchDownGestureRecognizer(target: self, action: #selector(tapHandler(_:)))
editArea.addGestureRecognizer(tap)
editArea.initTextStorage()
let tapGR = UITapGestureRecognizer(target: self, action: #selector(editMode))
tapGR.delegate = self
tapGR.numberOfTapsRequired = 2
view.addGestureRecognizer(tapGR)
editArea.imagesLoaderQueue.maxConcurrentOperationCount = 1
editArea.imagesLoaderQueue.qualityOfService = .userInteractive
super.viewDidLoad()
var items = [UIBarButtonItem]()
items.append(UIBarButtonItem(systemImageName: "magnifyingglass", target: self, selector: #selector(editorSearch)))
items.append(UIBarButtonItem.flexibleSpace())
items.append(UIBarButtonItem(systemImageName: "plus", target: self, selector: #selector(newNote)))
toolbarItems = items
self.addToolBar(textField: editArea, toolbar: self.getMarkdownToolbar())
NotificationCenter.default.addObserver(self, selector: #selector(themeObserver), name: UIApplication.didBecomeActiveNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(preferredContentSizeChanged), name: UIContentSizeCategory.didChangeNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(rotated), name: UIDevice.orientationDidChangeNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(refill), name: NSNotification.Name(rawValue: "es.fsnot.external.file.changed"), object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChangeFrame), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
editArea.keyboardDismissMode = .interactive
registerForKeyboardNotifications()
registerForAppStateNotifications()
}
@objc func rotated() {
guard isLandscape != nil else {
isLandscape = UIDevice.current.orientation.isLandscape
return
}
let isLand = UIDevice.current.orientation.isLandscape
if let landscape = self.isLandscape, landscape != isLand, !UIDevice.current.orientation.isFlat {
isLandscape = isLand
}
}
override func viewDidAppear(_ animated: Bool) {
editArea.isScrollEnabled = true
super.viewDidAppear(animated)
if editArea.textStorage.length == 0 && editArea.note?.previewState == false {
editArea.perform(#selector(becomeFirstResponder), with: nil, afterDelay: 0)
}
initLinksColor()
editArea.flashScrollIndicators()
initSwipes()
}
override func viewWillAppear(_ animated: Bool) {
updateTitle()
super.viewWillAppear(animated)
configureNavMenu()
navigationItem.largeTitleDisplayMode = .never
navigationController?.setToolbarHidden(false, animated: true)
navigationController?.toolbar.tintColor = UIColor.mainTheme
navigationController?.navigationBar.tintColor = UIColor.mainTheme
}
@objc func search() {
UIApplication.getVC().enableSearchFocus()
self.cancel()
}
@objc func newNote() {
UIApplication.getVC().createNote(content: "")
configureNavMenu()
}
override func viewWillDisappear(_ animated: Bool) {
editArea.endEditing(true)
UIApplication.getNC()?.navigationItem.searchController = nil
}
override var disablesAutomaticKeyboardDismissal: Bool {
return false
}
override var textInputMode: UITextInputMode? {
if let keyboard = UserDefaultsManagement.defaultKeyboard {
for mode in UITextInputMode.activeInputModes {
if mode.primaryLanguage == keyboard {
return mode
}
}
}
return super.textInputMode
}
public func updateTitle() {
navigationItem.title = note?.project.label
if #available(iOS 26.0, *) {
navigationItem.subtitle = note?.url.lastPathComponent
}
}
private func registerForKeyboardNotifications() {
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
}
private func unregisterFromKeyboardNotifications() {
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil)
}
private func registerForAppStateNotifications() {
NotificationCenter.default.addObserver(self, selector: #selector(appDidEnterBackground), name: UIApplication.didEnterBackgroundNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(appWillEnterForeground), name: UIApplication.willEnterForegroundNotification, object: nil)
}
@objc private func appDidEnterBackground() {
unregisterFromKeyboardNotifications()
}
@objc private func appWillEnterForeground() {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
self.registerForKeyboardNotifications()
}
}
public func configureNavMenu() {
guard let note = self.note else { return }
guard let menu = UIApplication.getVC().notesTable.makeBulkMenu(editor: true, note: note) else { return }
let buttonName =
editArea.note?.previewState == true
? "eye.slash"
: "eye"
let previewBarItem = UIBarButtonItem(systemImageName: buttonName, target: self, selector: #selector(togglePreview))
previewBarItem.tag = 5
navigationItem.rightBarButtonItems = [
UIBarButtonItem(systemImageName: "ellipsis.circle", menu: menu),
previewBarItem
]
}
public func fill(note: Note, selectedRange: NSRange? = nil, clearPreview: Bool = false, enableHandoff: Bool = true, completion: (() -> ())? = nil) {
if enableHandoff {
registerHandoff(for: note)
}
self.note = note
if !note.isLoaded {
note.load()
}
editArea.note = note
if note.previewState {
loadPreviewView()
completion?()
return
}
getPreviewView()?.removeFromSuperview()
fillEditor(note: note, selectedRange: selectedRange)
completion?()
}
private func fillEditor(note: Note, selectedRange: NSRange? = nil) {
guard editArea != nil else { return }
editArea.isNoteLoading = true
editArea.initUndoRedoButons()
view.backgroundColor = UIColor.dropDownColor
editArea.backgroundColor = UIColor.dropDownColor
if let content = note.content.mutableCopy() as? NSMutableAttributedString {
editArea.attributedText = content
}
if let scroll = editArea.inputAccessoryView as? UIScrollView {
scroll.contentOffset = .zero
}
editArea.delegate = self
let storage = editArea.textStorage
storage.updateCheckboxList()
editArea.typingAttributes[.font] = UserDefaultsManagement.noteFont
editArea.layoutManager.ensureLayout(for: editArea.textContainer)
editArea.layoutIfNeeded()
self.loadSelectedRange()
if let query = self.getSearchText(), query.count > 0 {
UIApplication.getVC().enableSearchFocus(string: query)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
self.openSearchWithText(query)
}
}
}
@objc public func clickOnButton() {
let vc = UIApplication.getVC()
guard let note = self.note else { return }
vc.notesTable.actionsSheet(notes: [note], showAll: true, presentController: self)
}
@objc func refill() {
guard let editArea = editArea else { return }
initLinksColor()
if let note = self.note {
let keyboardIsOpen = editArea.isFirstResponder
if keyboardIsOpen {
editArea.endEditing(true)
}
fill(note: note)
if keyboardIsOpen {
_ = editArea.becomeFirstResponder()
}
}
}
private var keyboardFrameChangeCount = 0
@objc func keyboardWillChangeFrame(_ notification: Notification) {
keyboardFrameChangeCount += 1
}
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
guard let note = self.note else { return true }
tagsHandler(affectedCharRange: range, text: text)
wikilinkHandler(textView: textView, text: text)
deleteUnusedImages(checkRange: range)
// New line
if text == "\n" {
let formatter = TextFormatter(textView: self.editArea, note: note)
formatter.newLine()
return false
}
// Tab
if text == "\t" {
let formatter = TextFormatter(textView: self.editArea, note: note)
formatter.tabKey()
return false
}
if let font = self.editArea.typingFont {
editArea.typingAttributes.removeAll()
editArea.typingAttributes[.font] = font
}
return true
}
private func tagsHandler(affectedCharRange: NSRange, text: String) {
guard UserDefaultsManagement.inlineTags else { return }
let textStorage = editArea.textStorage
// close dropdown
if ["", " ", "\t", "\n"].contains(text) {
if !dropDown.isHidden {
dropDown.hide()
}
return
}
// one char
guard text.count == 1 else { return }
let nextCharLocation = affectedCharRange.location + 1
let nextChar: String
if editArea.selectedRange.length == 0, nextCharLocation <= textStorage.length {
let nextCharRange = NSRange(location: affectedCharRange.location, length: 1)
nextChar = textStorage.mutableString.substring(with: nextCharRange)
} else {
nextChar = " "
}
if affectedCharRange.location > 0 {
let hashRange = NSRange(location: affectedCharRange.location - 1, length: 1)
let prevChar = (textStorage.string as NSString).substring(with: hashRange)
if prevChar == "#" && nextChar.isWhitespace {
let filteredTags = self.getAllTags().filter { $0.lowercased().starts(with: text.lowercased()) }
if filteredTags.isEmpty {
dropDown.hide()
} else {
dropDown.dataSource = filteredTags
complete(offset: hashRange.location, text: text)
}
return
}
}
let parRange = textStorage.mutableString.paragraphRange(for: NSRange(location: affectedCharRange.location, length: 0))
textStorage.mutableString.enumerateSubstrings(in: parRange, options: .byWords) { word, range, _, stop in
guard let word = word,
affectedCharRange.location <= range.upperBound,
affectedCharRange.location >= range.lowerBound,
range.location > 0 else {
return
}
let hashRange = NSRange(location: range.location - 1, length: 1)
let prevChar = (textStorage.string as NSString).substring(with: hashRange)
if prevChar == "#" && nextChar.isWhitespace {
let searchText = word + text
let filteredTags = self.getAllTags().filter { $0.lowercased().starts(with: searchText.lowercased()) }
if filteredTags.isEmpty {
self.dropDown.hide()
} else {
self.dropDown.dataSource = filteredTags
self.complete(offset: hashRange.location, range: range, text: text)
}
stop.pointee = true
}
}
}
private func getAllTags() -> [String] {
let vc = UIApplication.getVC()
var projects = [Project]()
if let project = Storage.shared().searchQuery.projects.first {
projects.append(project)
} else {
projects = Storage.shared().getProjects()
}
let allTags = vc.sidebarTableView.getAllTags(projects: projects)
return allTags
}
private func wikilinkHandler(textView: UITextView, text: String) {
guard text.count == 1, !["\n"].contains(text) else { return }
let textStorage = textView.textStorage
let location = textView.selectedRange.location
// Encoded offset for Emoji
guard let cursor = textView.cursorDistance else { return }
let parRange = textStorage.mutableString.paragraphRange(for: NSRange(location: location, length: 0))
let paragraph = textStorage.attributedSubstring(from: parRange).string
guard paragraph.contains("[[") && paragraph.contains("]]"),
let result = isBetweenBraces(location: cursor) else { return }
let word = result.0 + text
guard let titles = Storage.shared().getTitles(by: word) else {
dropDown.hide()
return
}
dropDown.dataSource = titles
let range = result.1
// Decode multibyte offset for Emoji like "🇺🇦"
let startIndex = textView.text.index(textView.text.startIndex, offsetBy: range.lowerBound + 2)
let startRange = NSRange(startIndex...startIndex, in: textView.text)
let replacementRange = NSRange(location: startRange.lowerBound, length: word.count)
complete(offset: replacementRange.location, replacementRange: replacementRange)
}
private func isBetweenBraces(location: Int) -> (String, NSRange)? {
let storage = editArea.textStorage
let string = Array(storage.string)
let length = storage.length
var firstLeftFound = false
var firstRigthFound = false
var rigthFound = false
var leftFound = false
var i = location - 1
var j = location
while i >= 0 {
let char = string[i]
if firstLeftFound {
leftFound = char == "["
break
}
if char.isNewline {
break
}
if char == "[" {
firstLeftFound = true
}
i -= 1
}
while length > j {
let char = string[j]
if firstRigthFound {
rigthFound = char == "]"
break
}
if char.isNewline {
break
}
if char == "]" {
firstRigthFound = true
}
j += 1
}
var result = String()
if leftFound && rigthFound {
result =
String(string[i...j])
result = result
.replacingOccurrences(of: "[[", with: "")
.replacingOccurrences(of: "]]", with: "")
return (result, NSRange(i...j))
}
return nil
}
private func complete(offset: Int? = nil, range: NSRange? = nil, text: String? = nil, replacementRange: NSRange? = nil) {
var endPosition: UITextPosition = editArea.endOfDocument
if let offset = offset,
let position = editArea.position(from: editArea.beginningOfDocument, offset: offset) {
endPosition = position
}
let rect = editArea.caretRect(for: endPosition)
let customView = UIView(frame: CGRect(x: rect.origin.x, y: rect.origin.y + 30, width: 200, height: 0))
editArea.addSubview(customView)
dropDown.cellHeight = 35
dropDown.textFont = UIFont.boldSystemFont(ofSize: 15)
dropDown.backgroundColor = UIColor.dropDownColor
dropDown.textColor = traitCollection.userInterfaceStyle == .dark ? UIColor.white : UIColor.gray
dropDown.anchorView = customView
dropDown.selectionAction = { [unowned self] (index: Int, item: String) in
customView.removeFromSuperview()
// WikiLinks
if let replacementRange = replacementRange {
editArea.undoManager?.beginUndoGrouping()
self.editArea.selectedRange = replacementRange
self.editArea.insertText(item)
editArea.undoManager?.endUndoGrouping()
return
}
if let range = range, let text = text {
let string = self.editArea.textStorage.mutableString.substring(with: range) + text
let addText = item.replacingOccurrences(of: string, with: "")
self.editArea.insertText(addText + " ")
} else if text != nil {
let addText = String(item.dropFirst())
self.editArea.insertText(addText + " ")
} else {
self.editArea.insertText(item + " ")
}
}
dropDown.show()
}
@objc public func scanTags() {
guard UserDefaultsManagement.inlineTags else { return }
guard let note = editArea.note else { return }
UIApplication.getVC().sidebarTableView.loadTags(notes: [note])
if let title = note.getAutoRenameTitle() {
UIApplication.getVC().notesTable.rename(note: note, to: title)
UIApplication.getEVC().updateTitle()
}
}
private func deleteUnusedImages(checkRange: NSRange) {
editArea.textStorage.enumerateAttribute(.attachment, in: checkRange) { (value, range, _) in
guard let meta = editArea.textStorage.getMeta(at: range.location) else { return }
do {
if let data = try? Data(contentsOf: meta.url) {
editArea.textStorage.addAttribute(.attachmentSave, value: data, range: range)
try FileManager.default.removeItem(at: meta.url)
}
} catch {
print(error)
}
}
}
private func deleteBackwardPressed(text: String) -> Bool {
if !self.isUndo, let char = text.cString(using: String.Encoding.utf8), strcmp(char, "\\b") == -92 {
return true
}
self.isUndo = false
return false
}
func textViewDidChangeSelection(_ textView: UITextView) {
if textView.isFirstResponder {
// Handoff needs update in cursor position cahnged
userActivity?.needsSave = true
saveSelectedRange()
}
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
saveSelectedRange()
}
func textViewDidChange(_ textView: UITextView) {
let vc = UIApplication.getVC()
//vc.cloudDriveManager?.metadataQuery.disableUpdates()
guard let note = self.note else { return }
// Prevent textStorage refresh in CloudDriveManager
note.modifiedLocalAt = Date()
self.storageQueue.cancelAllOperations()
let text = self.editArea.attributedText.mutableCopy() as? NSMutableAttributedString
let operation = BlockOperation()
operation.addExecutionBlock { [weak self] in
guard let self = self, let text = text else {return}
note.save(content: text)
if note.isEncrypted() && !note.isUnlocked() {
DispatchQueue.main.async {
self.cancel()
}
return
}
note.invalidateCache()
note.loadPreviewInfo()
vc.updateSpotlightIndex(notes: [note])
DispatchQueue.main.async {
self.rowUpdaterTimer.invalidate()
self.rowUpdaterTimer = Timer.scheduledTimer(timeInterval: 1.2, target: self, selector: #selector(self.updateCurrentRow), userInfo: nil, repeats: false)
self.tagsTimer?.invalidate()
self.tagsTimer = Timer.scheduledTimer(timeInterval: 2.5, target: self, selector: #selector(self.scanTags), userInfo: nil, repeats: false)
}
usleep(100000)
}
self.storageQueue.addOperation(operation)
editArea.typingAttributes.removeValue(forKey: .backgroundColor)
editArea.typingAttributes[.font] = UserDefaultsManagement.noteFont
editArea.initUndoRedoButons()
//vc.cloudDriveManager?.metadataQuery.enableUpdates()
}
@objc private func updateCurrentRow() {
let vc = UIApplication.getVC()
guard let note = self.note else { return }
vc.notesTable.moveRowUp(note: note)
vc.notesTable.reloadRows(notes: [note])
}
func getSearchText() -> String? {
if let search = UIApplication.getVC().navigationItem.searchController?.searchBar.text {
return search
}
return nil
}
@objc func keyboardWillShow(notification: NSNotification) {
keyboardFrameChangeCount = 0
guard let userInfo = notification.userInfo else { return }
guard var keyboardFrame: CGRect = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue else { return }
keyboardFrame = view.convert(keyboardFrame, from: nil)
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .left
paragraphStyle.lineSpacing = CGFloat(UserDefaultsManagement.editorLineSpacing)
self.editArea.typingAttributes[.paragraphStyle] = paragraphStyle
self.editArea.typingAttributes.removeValue(forKey: .link)
let keyboardHeight = keyboardFrame.height
let contentInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: keyboardHeight - 66, right: 0.0)
self.editArea.contentInset = contentInsets
self.editArea.scrollIndicatorInsets = contentInsets
}
@objc func keyboardWillHide(notification: NSNotification) {
let contentInsets = UIEdgeInsets.zero
editArea.contentInset = contentInsets
editArea.scrollIndicatorInsets = contentInsets
if isKeyboardClosedManually() {
// NO selection more
saveSelectedRangeZero()
}
if searchBar != nil {
hideSearch()
}
}
func isKeyboardClosedManually() -> Bool {
return keyboardFrameChangeCount > 2
}
func addToolBar(textField: UITextView, toolbar: UIToolbar) {
let scroll = UIScrollView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 50))
scroll.showsHorizontalScrollIndicator = false
scroll.contentSize = CGSize(width: toolbar.frame.width, height: 50)
scroll.addSubview(toolbar)
toolbar.frame.origin = .zero
textField.inputAccessoryView = scroll
}
public func getMarkdownToolbar() -> UIToolbar {
if #available(iOS 26.0, *) {
return getModernToolbar()
} else {
return getLegacyToolbar()
}
}
public func getModernToolbar() -> UIToolbar {
var items = [UIBarButtonItem]()
let todoButton = UIBarButtonItem(systemImageName: "checkmark.square", target: self, selector: #selector(EditorViewController.todoPressed))
items.append(todoButton)
if UserDefaultsManagement.inlineTags {
let tagButton = UIBarButtonItem(systemImageName: "tag", target: self, selector: #selector(EditorViewController.tagPressed))
items.append(tagButton)
}
let boldButton = UIBarButtonItem(systemImageName: "bold", target: self, selector: #selector(EditorViewController.boldPressed))
items.append(boldButton)
let italicButton = UIBarButtonItem(systemImageName: "italic", target: self, selector: #selector(EditorViewController.italicPressed))
italicButton.tag = 0x03
items.append(italicButton)
let headerButton = UIBarButtonItem(systemImageName: "textformat", target: self, selector: #selector(EditorViewController.headerPressed))
items.append(headerButton)
let wikiButton = UIBarButtonItem(systemImageName: "link", target: self, selector: #selector(EditorViewController.wikilink))
items.append(wikiButton)
let imageButton = UIBarButtonItem(systemImageName: "paperclip", target: self, selector: #selector(EditorViewController.insertFile))
items.append(imageButton)
let codeblockButton = UIBarButtonItem(systemImageName: "swift", target: self, selector: #selector(EditorViewController.codeBlockButton))
items.append(codeblockButton)
let quoteButton = UIBarButtonItem(systemImageName: "quote.bubble", target: self, selector: #selector(EditorViewController.quotePressed))
items.append(quoteButton)
let orderedListButton = UIBarButtonItem(systemImageName: "list.bullet", target: self, selector: #selector(EditorViewController.orderedListPressed))
items.append(orderedListButton)
let numberedListButton = UIBarButtonItem(systemImageName: "list.number", target: self, selector: #selector(EditorViewController.numberedListPressed))
items.append(numberedListButton)
let indentButton = UIBarButtonItem(systemImageName: "increase.indent", target: self, selector: #selector(EditorViewController.indentPressed))
items.append(indentButton)
let unindentButton = UIBarButtonItem(systemImageName: "decrease.indent", target: self, selector: #selector(EditorViewController.unIndentPressed))
items.append(unindentButton)
self.undoBarButton = UIBarButtonItem(systemImageName: "arrow.uturn.backward", target: self, selector: #selector(EditorViewController.undoPressed))
items.append(self.undoBarButton!)
self.redoBarButton = UIBarButtonItem(systemImageName: "arrow.uturn.forward", target: self, selector: #selector(EditorViewController.redoPressed))
items.append(self.redoBarButton!)
var totalWidth: CGFloat = 0
for item in items {
if item.tag == 0x03 {
item.width = 30
totalWidth += 30
} else {
item.width = 54
totalWidth += 54
}
}
let toolBar = UIToolbar(frame: CGRect(x: 0, y: 0, width: totalWidth, height: 50))
toolBar.setItems(items, animated: false)
toolBar.isUserInteractionEnabled = true
let appearance = UIToolbarAppearance()
appearance.configureWithOpaqueBackground()
appearance.backgroundColor = .darkGray
appearance.shadowColor = .clear
toolBar.standardAppearance = appearance
toolBar.scrollEdgeAppearance = appearance
return toolBar
}
private func getLegacyToolbar() -> UIToolbar {
var items = [UIBarButtonItem]()
let todoImage = UIImage(named: "toolbarTodo")?.resize(maxWidthHeight: 27)
let todoButton = UIBarButtonItem(image: todoImage, landscapeImagePhone: nil, style: .done, target: self, action: #selector(EditorViewController.todoPressed))
items.append(todoButton)
if UserDefaultsManagement.inlineTags {
let tagImage = UIImage(named: "toolbarTag")?.resize(maxWidthHeight: 25)
let tagButton = UIBarButtonItem(image: tagImage, landscapeImagePhone: nil, style: .done, target: self, action: #selector(EditorViewController.tagPressed))
items.append(tagButton)
}
let boldImage = UIImage(named: "toolbarBold")?.resize(maxWidthHeight: 21)
let boldButton = UIBarButtonItem(image: boldImage, landscapeImagePhone: nil, style: .done, target: self, action: #selector(EditorViewController.boldPressed))
items.append(boldButton)
let italicImage = UIImage(named: "toolbarItalic")?.resize(maxWidthHeight: 18)
let italicButton = UIBarButtonItem(image: italicImage, landscapeImagePhone: nil, style: .done, target: self, action: #selector(EditorViewController.italicPressed))
italicButton.tag = 0x03
items.append(italicButton)
let headerImage = UIImage(named: "toolbarHeader")?.resize(maxWidthHeight: 22)
let headerButton = UIBarButtonItem(image: headerImage, landscapeImagePhone: nil, style: .done, target: self, action: #selector(EditorViewController.headerPressed))
items.append(headerButton)
let wikiImage = UIImage(named: "toolbarWiki")?.resize(maxWidthHeight: 25)
let wikiButton = UIBarButtonItem(image: wikiImage, landscapeImagePhone: nil, style: .done, target: self, action: #selector(EditorViewController.wikilink))
items.append(wikiButton)
let toolbarImage = UIImage(named: "toolbarImage")?.resize(maxWidthHeight: 26)
let imageButton = UIBarButtonItem(image: toolbarImage, landscapeImagePhone: nil, style: .done, target: self, action: #selector(EditorViewController.insertFile))
items.append(imageButton)
let codeBlockImage = UIImage(named: "codeBlockAsset")?.resize(maxWidthHeight: 24)
let codeblockButton = UIBarButtonItem(image: codeBlockImage, landscapeImagePhone: nil, style: .done, target: self, action: #selector(EditorViewController.codeBlockButton))
items.append(codeblockButton)
let quoteImage = UIImage(named: "quote")?.resize(maxWidthHeight: 21)
let quoteButton = UIBarButtonItem(image: quoteImage, landscapeImagePhone: nil, style: .done, target: self, action: #selector(EditorViewController.quotePressed))
items.append(quoteButton)
let orderedListImage = UIImage(named: "ordered_list")?.resize(maxWidthHeight: 25)
let orderedListButton = UIBarButtonItem(image: orderedListImage, landscapeImagePhone: nil, style: .done, target: self, action: #selector(EditorViewController.orderedListPressed))
items.append(orderedListButton)
let numberedListImage = UIImage(named: "numbered_list")?.resize(maxWidthHeight: 25)
let numberedListButton = UIBarButtonItem(image: numberedListImage, landscapeImagePhone: nil, style: .done, target: self, action: #selector(EditorViewController.numberedListPressed))
items.append(numberedListButton)
let indentRightImage = UIImage(named: "toolbarIndentRight")?.resize(maxWidthHeight: 25)
let indentButton = UIBarButtonItem(image: indentRightImage, landscapeImagePhone: nil, style: .done, target: self, action: #selector(EditorViewController.indentPressed))
items.append(indentButton)
let indentLeftImage = UIImage(named: "toolbarIndentLeft")?.resize(maxWidthHeight: 25)
let unindentButton = UIBarButtonItem(image: indentLeftImage, landscapeImagePhone: nil, style: .done, target: self, action: #selector(EditorViewController.unIndentPressed))
items.append(unindentButton)
let undoImage = UIImage(named: "undo")?.resize(maxWidthHeight: 25)
let undoButton = UIBarButtonItem(image: undoImage, landscapeImagePhone: nil, style: .done, target: self, action: #selector(EditorViewController.undoPressed))
items.append(undoButton)
let redoImage = UIImage(named: "redo")?.resize(maxWidthHeight: 25)
let redoButton = UIBarButtonItem(image: redoImage, landscapeImagePhone: nil, style: .done, target: self, action: #selector(EditorViewController.redoPressed))
items.append(redoButton)
var width = CGFloat(0)
for item in items {
if item.tag == 0x03 {
item.width = 30
width += 30
} else {
item.width = 50
width += 50
}
}
let toolBar = UIToolbar(frame: CGRect.init(x: 0, y: 0, width: width, height: 50))
toolBar.backgroundColor = .darkGray
toolBar.isTranslucent = false
toolBar.tintColor = UIColor.mainTheme
toolBar.setItems(items, animated: false)
toolBar.isUserInteractionEnabled = true
return toolBar
}
@objc func boldPressed(){
if let note = note {
let formatter = TextFormatter(textView: editArea, note: note)
formatter.bold()
}
}
@objc func tagPressed(){
editArea.insertText("#")
let location = editArea.selectedRange.location
let vc = UIApplication.getVC()
var projects = [Project]()
if let project = Storage.shared().searchQuery.projects.first {
projects.append(project)
} else {
projects = Storage.shared().getProjects()
}
let tags = vc.sidebarTableView.getAllTags(projects: projects)
self.dropDown.dataSource = tags
self.complete(offset: location)
}
@objc func italicPressed(){
if let note = note {
let formatter = TextFormatter(textView: editArea, note: note)
formatter.italic()
}
}
@objc func strikePressed(){
if let note = note {
let formatter = TextFormatter(textView: editArea, note: note)
formatter.strike()
}
}
@objc func underlinePressed(){
if let note = note {
let formatter = TextFormatter(textView: editArea, note: note)
formatter.underline()
}
}
@objc func indentPressed(){
if let note = note {
let formatter = TextFormatter(textView: editArea, note: note)
formatter.tab()
}
}
@objc func unIndentPressed(){
if let note = note {
let formatter = TextFormatter(textView: editArea, note: note)
formatter.unTab()
}
}
@objc func headerPressed() {
if let note = note {
let formatter = TextFormatter(textView: editArea, note: note)
formatter.header("#")
}
}
@objc func wikilink() {
guard let note = note else { return }
let formatter = TextFormatter(textView: editArea, note: note)
formatter.wikiLink()
guard let titles = Storage.shared().getTitles() else { return }
self.dropDown.dataSource = titles
self.complete(offset: editArea.selectedRange.location, replacementRange: editArea.selectedRange)
}
@objc func codeBlockButton() {
if let note = note {
let formatter = TextFormatter(textView: editArea, note: note)
formatter.codeBlock()
}
}
@objc func quotePressed() {
if let note = note {
let formatter = TextFormatter(textView: editArea, note: note)
formatter.quote()
AudioServicesPlaySystemSound(1519)
}
}
@objc func todoPressed() {
if let note = note {
let formatter = TextFormatter(textView: editArea, note: note)
formatter.todo()
AudioServicesPlaySystemSound(1519)
}
}
@objc func orderedListPressed() {
if let note = note {
let formatter = TextFormatter(textView: editArea, note: note)
formatter.list()
AudioServicesPlaySystemSound(1519)
}
}
@objc func numberedListPressed() {
if let note = note {
let formatter = TextFormatter(textView: editArea, note: note)
formatter.orderedList()
AudioServicesPlaySystemSound(1519)
}
}
@objc func insertFile() {
let actionSheet = UIAlertController(title: NSLocalizedString("Images source:", comment: ""), message: nil, preferredStyle: .actionSheet)
let photos = UIAlertAction(title: NSLocalizedString("Photos", comment: ""), style: .default, handler: { _ in
var conf = PHPickerConfiguration(photoLibrary: .shared())
conf.selectionLimit = 10
let picker = PHPickerViewController(configuration: conf)
picker.delegate = self
self.present(picker, animated: true, completion: nil)
})
actionSheet.addAction(photos)
let iCloudDrive = UIAlertAction(title: NSLocalizedString("Documents", comment: ""), style: .default, handler: { _ in
let documentPickerController = UIDocumentPickerViewController(forOpeningContentTypes: [.data], asCopy: true)
documentPickerController.delegate = self
documentPickerController.allowsMultipleSelection = true
documentPickerController.modalPresentationStyle = .formSheet
self.present(documentPickerController, animated: true, completion: nil)
})
actionSheet.addAction(iCloudDrive)
let cancel = UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .destructive, handler: { _ in
})
actionSheet.addAction(cancel)
if let view = self.editArea.superview {
actionSheet.popoverPresentationController?.sourceView = view
actionSheet.popoverPresentationController?.sourceRect = CGRect(x: view.bounds.size.width / 2.0, y: view.bounds.size.height, width: 2.0, height: 1.0)
}
present(actionSheet, animated: true, completion: nil)
}
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
for url in urls {
guard let data = try? Data(contentsOf: url),
let mutable = NSMutableAttributedString.build(data: data, preferredName: url.lastPathComponent) else { continue }
DispatchQueue.main.async {
self.editArea.insertAttributedText(mutable)
}
}
}
@objc func themeObserver() {
guard
UIApplication.shared.applicationState == .active,
let style = UIApplication.shared
.connectedScenes
.compactMap({ $0 as? UIWindowScene })
.first?
.traitCollection
.userInterfaceStyle
else { return }
guard style != lastStyle else { return }
lastStyle = style
NotesTextProcessor.hl = nil
UIApplication.getEVC().refill()
}
@objc func preferredContentSizeChanged() {
if let n = note {
self.fill(note: n)
}
}
@objc func undoPressed() {
guard let ea = UIApplication.getEVC().editArea, let um = ea.undoManager else { return }
um.undo()
ea.initUndoRedoButons()
}
@objc func redoPressed() {
guard let ea = UIApplication.getEVC().editArea, let um = ea.undoManager else { return }
um.redo()
ea.initUndoRedoButons()
}
func initLinksColor() {
var linkAttributes: [NSAttributedString.Key : Any] = [
.foregroundColor: UIColor.linksColor
]
linkAttributes[.underlineColor] = UIColor.lightGray
linkAttributes[.underlineStyle] = 0
if editArea != nil {
editArea.linkTextAttributes = linkAttributes
}
}
@objc private func tapHandler(_ sender: SingleTouchDownGestureRecognizer) {
let myTextView = sender.view as! EditTextView
guard let characterIndex = sender.touchCharIndex else { return}
let char = myTextView.textStorage.mutableString.substring(with: NSRange(location: characterIndex, length: 1))
// Toggle todo on click
if characterIndex + 1 < myTextView.textStorage.length, char != "\n", self.isTodo(location: characterIndex, textView: myTextView), let note = self.note {
let textFormatter = TextFormatter(textView: self.editArea!, note: note)
textFormatter.toggleTodo(characterIndex)
self.editArea.selectedTextRange = sender.selectedRange
Timer.scheduledTimer(withTimeInterval: 0.05, repeats: false) { _ in
self.editArea.isAllowedScrollRect = true
}
AudioServicesPlaySystemSound(1519)
return
}
// Image preview/selection on click
if self.editArea.isImage(at: characterIndex) {
guard let meta = myTextView.textStorage.getMeta(at: characterIndex) else { return }
if let data = try? Data(contentsOf: meta.url), let someImage = UIImage(data: data) {
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let imagePreviewViewController = storyBoard.instantiateViewController(withIdentifier: "imagePreviewViewController") as! ImagePreviewViewController
imagePreviewViewController.image = someImage
imagePreviewViewController.url = meta.url
imagePreviewViewController.note = note
navigationController?.pushViewController(imagePreviewViewController, animated: true)
} else if (FileManager.default.fileExists(atPath: meta.url.path)) {
quickLook(url: meta.url)
}
return
}
// Links
if self.editArea.isLink(at: characterIndex) {
guard let path = self.editArea.textStorage.attribute(.link, at: characterIndex, effectiveRange: nil) as? String else { return }
if path.starts(with: "fsnotes://find?id=") {
openWikiLink(query: path)
return
}
if path.starts(with: "fsnotes://open/?tag=") {
if let url = URL(string: path) {
UIApplication.shared.open(url, options: [:])
}
return
}
if self.editArea.isFirstResponder {
DispatchQueue.main.async {
self.editArea.selectedRange = NSRange(location: characterIndex, length: 0)
}
return
}
if let url = URL(string: path) {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
}
}
public func openWikiLink(query: String) {
guard let query = query
.replacingOccurrences(of: "fsnotes://find?id=", with: "")
.removingPercentEncoding else { return }
guard let note = note else { return }
if let note = Storage.instance?.getBy(title: query, exclude: note) {
fill(note: note)
} else if let note = Storage.instance?.getBy(fileName: query, exclude: note) {
fill(note: note)
} else {
let vc = UIApplication.getVC()
navigationController?.popViewController(animated: true)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
vc.shouldReturnToControllerIndex = true
vc.loadSearchController(query: query)
vc.buildSearchQuery()
vc.reloadNotesTable()
}
}
}
@objc private func imageTapHandler(_ sender: SingleImageTouchDownGestureRecognizer) {
guard let view = sender.view as? UITextView else { return }
let layoutManager = view.layoutManager
let location = sender.location(in: view)
var characterIndex = layoutManager.characterIndex(for: location, in: view.textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
DispatchQueue.main.async {
view.becomeFirstResponder()
if sender.isRightBorderTap {
characterIndex += 1
}
view.selectedRange = NSRange(location: characterIndex, length: 0)
}
}
private func isTodo(location: Int, textView: UITextView) -> Bool {
let storage = textView.textStorage
if storage.attribute(.todo, at: location, effectiveRange: nil) != nil {
return true
}
let range = (storage.string as NSString).paragraphRange(for: NSRange(location: location, length: 0))
let string = storage.attributedSubstring(from: range).string as NSString
var length = string.range(of: "- [ ]").length
if length == 0 {
length = string.range(of: "- [x]").length
}
if length > 0 {
let upper = range.location + length
if location >= range.location && location <= upper {
return true
}
}
return false
}
public func getMoreButton() -> UIBarButtonItem {
let config = UIImage.SymbolConfiguration(pointSize: 23, weight: .light, scale: .default)
let image = UIImage(systemName: "ellipsis.circle", withConfiguration: config)
let menuBarItem = UIBarButtonItem(image: image, style: .plain, target: self, action: #selector(clickOnButton))
menuBarItem.tintColor = UIColor.mainTheme
return menuBarItem
}
@IBAction func editMode() {
if editArea.note?.previewState == true {
togglePreview()
_ = editArea.becomeFirstResponder()
}
}
public func getPreviewView() -> MPreviewView? {
for sub in self.view.subviews {
if sub.isKind(of: MPreviewView.self) {
if let view = sub as? MPreviewView {
return view
}
}
}
return nil
}
@objc public func cancel() {
navigationController?.popViewController(animated: true)
}
@objc public func togglePreview() {
guard let unwrappedNote = self.note, let note = Storage.shared().getBy(url: unwrappedNote.url) else { return }
note.loadPreviewState()
if note.previewState {
note.previewState = false
getPreviewView()?.removeFromSuperview()
fillEditor(note: note)
} else {
note.previewState = true
editArea.endEditing(true)
loadPreviewView()
}
let buttonName = note.previewState ? "eye.slash" : "eye"
if let buttonBar = navigationItem.rightBarButtonItems?.first(where: { $0.tag == 5 }),
let button = buttonBar.customView as? UIButton {
let config = UIImage.SymbolConfiguration(pointSize: 20, weight: .light, scale: .default)
let image = UIImage(systemName: buttonName, withConfiguration: config)?.imageWithColor(color1: UIColor.mainTheme)
button.setImage(image, for: .normal)
}
// Handoff needs update in cursor position changed
userActivity?.needsSave = true
note.project.saveNotesPreview()
}
public func loadPreviewView() {
guard let note = editArea.note else { return }
var previewView: MPreviewView?
previewView = getPreviewView()
if previewView == nil {
let newView = MPreviewView(frame: self.view.frame, note: note, closure: {})
newView.backgroundColor = UIColor.dropDownColor
view.addSubview(newView)
newView.translatesAutoresizingMaskIntoConstraints = false
view.leadingAnchor.constraint(equalTo: newView.leadingAnchor).isActive = true
view.trailingAnchor.constraint(equalTo: newView.trailingAnchor).isActive = true
view.topAnchor.constraint(equalTo: newView.topAnchor).isActive = true
view.bottomAnchor.constraint(equalTo: newView.bottomAnchor).isActive = true
}
guard let previewView = previewView else { return }
previewView.clean()
previewView.load(note: note, force: true)
}
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
if URL.absoluteString.starts(with: "fsnotes://find?id=") {
if interaction == .invokeDefaultAction {
openWikiLink(query: URL.absoluteString)
}
return false
}
if URL.absoluteString.starts(with: "fsnotes://open/?tag=") {
if interaction == .invokeDefaultAction {
UIApplication.shared.open(URL, options: [:])
}
// if textView.isFirstResponder {
// UIApplication.shared.open(URL, options: [:])
// }
return false
}
if textView.isFirstResponder {
DispatchQueue.main.async {
textView.selectedRange = NSRange(location: characterRange.upperBound, length: 0)
}
if interaction == .presentActions {
let pathKey = NSAttributedString.Key(rawValue: "co.fluder.fsnotes.image.path")
if nil != textView.textStorage.attribute(pathKey, at: characterRange.location, effectiveRange: nil) {
return false
}
return true
}
return false
}
// Skip images (fixes glitch bug)
let pathKey = NSAttributedString.Key(rawValue: "co.fluder.fsnotes.image.path")
let attr = textView.textStorage.attribute(pathKey, at: characterRange.location, effectiveRange: nil)
if attr != nil && !textView.isFirstResponder {
return false
}
return true
}
func textView(_ textView: UITextView, shouldInteractWith textAttachment: NSTextAttachment, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
return false
}
func textViewDidEndEditing(_ textView: UITextView) {
editArea.keyboardIsOpened = true
editArea.callCounter = 0
}
/*
Handoff methods
*/
public func registerHandoff(for note: Note) {
let updateDict: [String: String] = ["note-file-name": note.name]
let activity = NSUserActivity(activityType: "es.fsnot.handoff-open-note")
activity.isEligibleForHandoff = true
activity.addUserInfoEntries(from: updateDict)
activity.title = NSLocalizedString("Open Note", comment: "Document opened")
self.userActivity = activity
self.userActivity?.becomeCurrent()
}
public func load(note: Note) {
let evc = UIApplication.getEVC()
evc.editArea.resignFirstResponder()
evc.fill(note: note, clearPreview: true, enableHandoff: false) {
UIApplication.getVC().openEditorViewController()
}
}
override func restoreUserActivityState(_ activity: NSUserActivity) {
if let id = activity.userInfo?["kCSSearchableItemActivityIdentifier"] as? String {
let url = URL(fileURLWithPath: id)
var note = Storage.shared().getBy(url: url)
if nil === note {
note = Storage.shared().addNote(url: url)
}
if let note = note {
load(note: note)
}
return
}
guard let name = activity.userInfo?["note-file-name"] as? String,
let position = activity.userInfo?["position"] as? String,
let note = Storage.shared().getBy(name: name)
else { return }
let evc = UIApplication.getEVC()
evc.editArea.resignFirstResponder()
evc.fill(note: note, clearPreview: true, enableHandoff: false) {
UIApplication.getVC().openEditorViewController()
if let pos = Int(position), pos > -1, evc.editArea.textStorage.length >= pos {
evc.editArea.becomeFirstResponder()
evc.editArea.selectedRange = NSRange(location: pos, length: 0)
}
}
}
override func updateUserActivityState(_ activity: NSUserActivity) {
guard let note = editArea.note else { return }
let position =
editArea.isFirstResponder ? editArea.selectedRange.location : -1
let state = note.previewState ? "preview" : "editor"
let data =
[
"note-file-name": note.name,
"position": String(position),
"state": state
]
activity.addUserInfoEntries(from: data)
}
@available(iOS 14, *)
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
picker.dismiss(animated: true, completion: nil)
for result in results {
result.itemProvider.loadObject(ofClass: UIImage.self, completionHandler: { (object, error) in
guard let photo = object as? UIImage, let imageData = photo.jpgData else { return }
let attachment = NSTextAttachment()
let mutable = NSMutableAttributedString(attachment: attachment)
mutable.addAttributes([
.attachmentSave: imageData,
.attachmentUrl: URL(fileURLWithPath: "/tmp/" + UUID().uuidString + ".jpg"),
.attachmentPath: String()
], range: NSRange(location: 0, length: 1))
mutable.append(NSAttributedString(string: "\n\n"))
DispatchQueue.main.async {
self.editArea.insertAttributedText(mutable)
}
})
}
}
// Swipe controller from UITextView center
// https://stackoverflow.com/questions/22244688/navigation-pop-view-when-swipe-right-like-instagram-iphone-app-how-i-achieve-thi/22244990#22244990
public func initSwipes() {
guard let popGestureRecognizer = self.navigationController?.interactivePopGestureRecognizer else { return }
if let targets = popGestureRecognizer.value(forKey: "targets") as? NSMutableArray {
let gestureRecognizer = UIPanGestureRecognizer()
gestureRecognizer.setValue(targets, forKey: "targets")
self.view.gestureRecognizers?.removeAll()
self.view.addGestureRecognizer(gestureRecognizer)
let tapGR = UITapGestureRecognizer(target: self, action: #selector(editMode))
tapGR.delegate = self
tapGR.numberOfTapsRequired = 2
self.view.addGestureRecognizer(tapGR)
}
}
func saveSelectedRangeZero() {
guard let note = editArea.note, !editArea.isNoteLoading else { return }
note.setSelectedRange(range: nil)
saveScrollPosition()
}
func saveScrollPosition() {
guard !editArea.isUpdating else { return }
guard let note = editArea.note, !editArea.isNoteLoading else { return }
let layoutManager = editArea.layoutManager
let textStorage = editArea.textStorage
let visibleY = editArea.contentOffset.y
guard textStorage.length > 0 else {
note.scrollPosition = 0
note.scrollOffset = 0
return
}
let glyphRange = layoutManager.glyphRange(
forBoundingRect: CGRect(x: 0, y: visibleY, width: editArea.bounds.width, height: 1),
in: editArea.textContainer
)
guard glyphRange.location != NSNotFound else {
note.scrollPosition = 0
note.scrollOffset = 0
return
}
let numberOfGlyphs = layoutManager.numberOfGlyphs
guard glyphRange.location < numberOfGlyphs else {
note.scrollPosition = 0
note.scrollOffset = 0
return
}
let charIndex = layoutManager.characterIndexForGlyph(at: glyphRange.location)
guard charIndex < textStorage.length else {
note.scrollPosition = 0
note.scrollOffset = 0
return
}
let glyphRect = layoutManager.boundingRect(
forGlyphRange: NSRange(location: glyphRange.location, length: 1),
in: editArea.textContainer
)
note.scrollPosition = charIndex
note.scrollOffset = visibleY - glyphRect.minY
}
func saveSelectedRange() {
guard let note = editArea.note, !editArea.isNoteLoading else { return }
note.setSelectedRange(range: editArea.isFirstResponder ? editArea.selectedRange : nil)
saveScrollPosition()
}
func loadSelectedRange() {
guard let note = editArea.note else { return }
if let range = note.getSelectedRange(), range.upperBound <= editArea.textStorage.length {
editArea.selectedRange = range
_ = editArea.becomeFirstResponder()
}
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
if let index = note.scrollPosition, index < self.editArea.textStorage.length {
let layoutManager = self.editArea.layoutManager
let glyphIndex = layoutManager.glyphIndexForCharacter(at: index)
let glyphRect = layoutManager.boundingRect(
forGlyphRange: NSRange(location: glyphIndex, length: 1),
in: self.editArea.textContainer
)
let targetY = glyphRect.minY + (note.scrollOffset ?? 0)
let maxY = max(0, self.editArea.contentSize.height - self.editArea.bounds.height)
let finalY = min(max(0, targetY), maxY)
self.editArea.contentOffset = CGPoint(x: 0, y: finalY)
} else {
self.editArea.contentOffset = .zero
}
self.editArea.isNoteLoading = false
}
}
deinit {
NotificationCenter.default.removeObserver(self)
}
}
================================================
FILE: FSNotes iOS/Extensions/UIApplication+.swift
================================================
//
// UIApplication.swift
// FSNotes iOS
//
// Created by Oleksandr Glushchenko on 9/21/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import UIKit
extension UIApplication {
// MARK: - Scene Delegate Access
static func getSceneDelegate() -> SceneDelegate? {
guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let sceneDelegate = windowScene.delegate as? SceneDelegate else {
return nil
}
return sceneDelegate
}
// MARK: - View Controllers Access
static func getVC() -> ViewController {
guard let sceneDelegate = getSceneDelegate() else {
fatalError("SceneDelegate not found")
}
return sceneDelegate.listController
}
static func getEVC() -> EditorViewController {
guard let sceneDelegate = getSceneDelegate() else {
fatalError("SceneDelegate not found")
}
return sceneDelegate.editorController
}
static func getNC() -> MainNavigationController? {
guard let sceneDelegate = getSceneDelegate() else {
return nil
}
return sceneDelegate.mainController
}
// MARK: - App Delegate Access
static func getDelegate() -> AppDelegate {
return UIApplication.shared.delegate as! AppDelegate
}
// MARK: - Window Access (Optional Helper)
static func getWindow() -> UIWindow? {
return getSceneDelegate()?.window
}
}
================================================
FILE: FSNotes iOS/Extensions/UIBarButtonItem+.swift
================================================
//
// UIBarButton+.swift
// FSNotes
//
// Created by Oleksandr Hlushchenko on 15.11.2025.
// Copyright © 2025 Oleksandr Hlushchenko. All rights reserved.
//
import UIKit
extension UIBarButtonItem {
convenience init(systemImageName: String, target: Any, selector: Selector) {
let config = UIImage.SymbolConfiguration(pointSize: 20, weight: .light, scale: .default)
let image = UIImage(systemName: systemImageName, withConfiguration: config)?.imageWithColor(color1: UIColor.mainTheme)
let button = UIButton(type: .system)
button.setImage(image, for: .normal)
button.tintColor = .mainTheme
button.addTarget(target, action: selector, for: .touchUpInside)
self.init(customView: button)
}
convenience init(systemImageName: String, menu: UIMenu) {
let config = UIImage.SymbolConfiguration(pointSize: 20, weight: .light)
let image = UIImage(systemName: systemImageName, withConfiguration: config)?
.imageWithColor(color1: .mainTheme)
let button = UIButton(type: .system)
button.setImage(image, for: .normal)
button.tintColor = .mainTheme
button.menu = menu
button.showsMenuAsPrimaryAction = true
button.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
self.init(customView: button)
}
}
================================================
FILE: FSNotes iOS/Extensions/UIColor+.swift
================================================
//
// UIColor+.swift
// FSNotes
//
// Created by Oleksandr Hlushchenko on 12.05.2023.
// Copyright © 2023 Oleksandr Hlushchenko. All rights reserved.
//
import UIKit
extension UIColor {
public static let mainTheme = UIColor(red: 0.08, green: 0.60, blue: 0.85, alpha: 1.00)
public static var previewColor: UIColor {
return UIColor { (traits) -> UIColor in
return traits.userInterfaceStyle == .dark ?
UIColor(red: 0.85, green: 0.87, blue: 0.90, alpha: 1.00) :
UIColor(red: 0.50, green: 0.56, blue: 0.65, alpha: 1.00)
}
}
public static var sidebar: UIColor {
return UIColor { (traits) -> UIColor in
return traits.userInterfaceStyle == .dark ?
UIColor(red: 0.11, green: 0.11, blue: 0.11, alpha: 1.00) :
UIColor(red: 0.97, green: 0.97, blue: 0.97, alpha: 1.00)
}
}
public static var currentSidebarCell: UIColor {
return UIColor { (traits) -> UIColor in
return traits.userInterfaceStyle == .dark ?
UIColor(red: 0.41, green: 0.39, blue: 0.45, alpha: 1.00) :
UIColor(red: 0.81, green: 0.87, blue: 0.95, alpha: 1.00)
}
}
public static var codeBackground: UIColor {
return UIColor { (traits) -> UIColor in
return traits.userInterfaceStyle == .dark ?
UIColor(red: 0.27, green: 0.27, blue: 0.27, alpha: 1.00) :
UIColor(red: 0.94, green: 0.95, blue: 0.95, alpha: 1.00)
}
}
public static var whiteBlack: UIColor {
return UIColor { (traits) -> UIColor in
return traits.userInterfaceStyle == .dark ?
UIColor(red: 0.00, green: 0.00, blue: 0.00, alpha: 1.00) :
UIColor(red: 1.00, green: 1.00, blue: 1.00, alpha: 1.00)
}
}
// Black for normal, white for dark
public static var blackWhite: UIColor {
return UIColor { (traits) -> UIColor in
return traits.userInterfaceStyle == .dark ?
UIColor(red: 1.00, green: 1.00, blue: 1.00, alpha: 1.00) :
UIColor(red: 0.00, green: 0.00, blue: 0.00, alpha: 1.00)
}
}
public static var toolbarTint: UIColor {
return UIColor { (traits) -> UIColor in
return traits.userInterfaceStyle == .dark ?
UIColor(red: 0.49, green: 0.92, blue: 0.63, alpha: 1.00) :
UIColor(red: 0.30, green: 0.55, blue: 0.90, alpha: 1.00)
}
}
public static var toolbarBorder: UIColor {
return UIColor { (traits) -> UIColor in
return traits.userInterfaceStyle == .dark ?
UIColor(red: 0.22, green: 0.22, blue: 0.22, alpha: 1.00) :
UIColor(red: 0.84, green: 0.84, blue: 0.87, alpha: 1.00)
}
}
public static var dropDownColor: UIColor {
return UIColor { (traits) -> UIColor in
return traits.userInterfaceStyle == .dark ?
UIColor(red: 0.00, green: 0.00, blue: 0.00, alpha: 1.00) :
UIColor(red: 0.98, green: 0.98, blue: 0.98, alpha: 1.00)
}
}
public static var wikiColor: UIColor {
return UIColor { (traits) -> UIColor in
return traits.userInterfaceStyle == .dark ?
UIColor(red: 0.00, green: 0.45, blue: 0.15, alpha: 1.00) :
UIColor(red: 0.29, green: 0.35, blue: 0.60, alpha: 1.00)
}
}
public static var highlightColor: UIColor {
return UIColor { (traits) -> UIColor in
return traits.userInterfaceStyle == .dark ?
UIColor(red: 0.20, green: 0.55, blue: 0.07, alpha: 1.00) :
UIColor(red: 1.00, green: 0.90, blue: 0.70, alpha: 1.00)
}
}
public static var linksColor: UIColor {
return UIColor { (traits) -> UIColor in
return traits.userInterfaceStyle == .dark ?
UIColor(red: 0.08, green: 0.60, blue: 0.85, alpha: 1.00) :
UIColor(red: 0.08, green: 0.60, blue: 0.85, alpha: 1.00)
}
}
public static func getBy(hex: String) -> UIColor {
var cString:String = hex.trimmingCharacters(in: .whitespacesAndNewlines).uppercased()
if (cString.hasPrefix("#")) {
cString.remove(at: cString.startIndex)
}
if ((cString.count) != 6) {
return UIColor.gray
}
var rgbValue:UInt64 = 0
Scanner(string: cString).scanHexInt64(&rgbValue)
return UIColor(
red: CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0,
green: CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0,
blue: CGFloat(rgbValue & 0x0000FF) / 255.0,
alpha: CGFloat(1.0)
)
}
var hexString: String {
var red: CGFloat = 0
var green: CGFloat = 0
var blue: CGFloat = 0
var alpha: CGFloat = 0
guard self.getRed(&red, green: &green, blue: &blue, alpha: &alpha) else {
return "#ffffff"
}
let rgb: Int = (Int)(red * 255) << 16 | (Int)(green * 255) << 8 | (Int)(blue * 255) << 0
return String(format: "#%06x", rgb)
}
}
================================================
FILE: FSNotes iOS/Extensions/UIFont+.swift
================================================
//
// UIFont+.swift
// FSNotes
//
// Created by Oleksandr Glushchenko on 3/6/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import UIKit
extension UIFont {
var isItalic: Bool {
return fontDescriptor.symbolicTraits.contains(.traitItalic)
}
func bold() -> UIFont {
if let descriptor = fontDescriptor.withSymbolicTraits(.traitBold) {
return UIFont(descriptor: descriptor, size: 0)
}
return UserDefaultsManagement.noteFont
}
private func buildFont(symTraits: UIFontDescriptor.SymbolicTraits?) -> UIFont {
var font: UIFont
if let traits = symTraits, let descriptor = fontDescriptor.withSymbolicTraits(traits) {
font = UIFont(descriptor: descriptor, size: descriptor.pointSize)
} else {
font = UserDefaultsManagement.noteFont
font.withSize(fontDescriptor.pointSize)
return font
}
return font
}
public func getAttachmentHeight() -> Double {
return Double(pointSize) + 6
}
}
================================================
FILE: FSNotes iOS/Extensions/UIImage+.swift
================================================
//
// UIImage+.swift
// FSNotes iOS
//
// Created by Oleksandr Glushchenko on 6/5/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import UIKit
extension UIImage {
func alpha(_ value:CGFloat) -> UIImage {
UIGraphicsBeginImageContextWithOptions(size, false, scale)
draw(at: CGPoint.zero, blendMode: .normal, alpha: value)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!
}
func resize(maxWidthHeight : Double)-> UIImage? {
let actualHeight = Double(size.height)
let actualWidth = Double(size.width)
var maxWidth = 0.0
var maxHeight = 0.0
if actualWidth > actualHeight {
maxWidth = maxWidthHeight
let per = (100.0 * maxWidthHeight / actualWidth)
maxHeight = (actualHeight * per) / 100.0
}else{
maxHeight = maxWidthHeight
let per = (100.0 * maxWidthHeight / actualHeight)
maxWidth = (actualWidth * per) / 100.0
}
let hasAlpha = true
let scale: CGFloat = 0.0
UIGraphicsBeginImageContextWithOptions(CGSize(width: maxWidth, height: maxHeight), !hasAlpha, scale)
self.draw(in: CGRect(origin: .zero, size: CGSize(width: maxWidth, height: maxHeight)))
let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
return scaledImage
}
func resize(height : Double)-> UIImage? {
let actualHeight = Double(size.height)
let actualWidth = Double(size.width)
var maxWidth = 0.0
var maxHeight = 0.0
var per: Double = 0
if actualWidth < actualHeight {
per = (70 / actualWidth)
maxWidth = (actualWidth * per)
maxHeight = (actualHeight * per)
} else{
per = (70 / actualHeight)
maxWidth = (actualWidth * per)
maxHeight = (actualHeight * per)
}
let newSize = CGSize(width: maxWidth, height: maxHeight)
let renderer = UIGraphicsImageRenderer(size: newSize)
let image = renderer.image { (context) in
self.draw(in: CGRect(origin: CGPoint(x: 0, y: 0), size: newSize))
}
return image
}
func croppedInRect(rect: CGRect) -> UIImage {
func rad(_ degree: Double) -> CGFloat {
return CGFloat(degree / 180.0 * .pi)
}
var rectTransform: CGAffineTransform
switch imageOrientation {
case .left:
rectTransform = CGAffineTransform(rotationAngle: rad(90)).translatedBy(x: 0, y: -self.size.height)
case .right:
rectTransform = CGAffineTransform(rotationAngle: rad(-90)).translatedBy(x: -self.size.width, y: 0)
case .down:
rectTransform = CGAffineTransform(rotationAngle: rad(-180)).translatedBy(x: -self.size.width, y: -self.size.height)
default:
rectTransform = .identity
}
rectTransform = rectTransform.scaledBy(x: self.scale, y: self.scale)
let imageRef = self.cgImage!.cropping(to: rect.applying(rectTransform))
let result = UIImage(cgImage: imageRef!, scale: self.scale, orientation: self.imageOrientation)
return result
}
public func getScale() -> Int {
let actualHeight = Double(size.height)
let actualWidth = Double(size.width)
if actualWidth < actualHeight {
return Int(70 / actualWidth)
} else{
return Int(70 / actualHeight)
}
}
public var jpgData: Data? {
return self.jpegData(compressionQuality: 1)
}
public static func emptyImage(with size: CGSize) -> UIImage? {
let renderer = UIGraphicsImageRenderer(size: size)
let img = renderer.image { ctx in
let border = UIColor.blackWhite
ctx.cgContext.setStrokeColor(border.cgColor)
ctx.cgContext.setLineWidth(1)
let rectangle = CGRect(x: 0, y: 0, width: size.width, height: size.height)
ctx.cgContext.addRect(rectangle)
ctx.cgContext.drawPath(using: .stroke)
}
return img
}
public func rounded(radius: CGFloat) -> UIImage {
let rect = CGRect(origin: .zero, size: size)
UIGraphicsBeginImageContextWithOptions(size, false, 0)
UIBezierPath(roundedRect: rect, cornerRadius: radius).addClip()
draw(in: rect)
return UIGraphicsGetImageFromCurrentImageContext()!
}
public func imageWithColor(color1: UIColor) -> UIImage {
UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
color1.setFill()
let context = UIGraphicsGetCurrentContext()
context?.translateBy(x: 0, y: self.size.height)
context?.scaleBy(x: 1.0, y: -1.0)
context?.setBlendMode(CGBlendMode.normal)
let rect = CGRect(origin: .zero, size: CGSize(width: self.size.width, height: self.size.height))
context?.clip(to: rect, mask: self.cgImage!)
context?.fill(rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!
}
func resized(to newSize: CGSize) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)
defer { UIGraphicsEndImageContext() }
draw(in: CGRect(origin: .zero, size: newSize))
return UIGraphicsGetImageFromCurrentImageContext()
}
}
================================================
FILE: FSNotes iOS/Extensions/UITextView+.swift
================================================
//
// UITextView+.swift
// FSNotes iOS
//
// Created by Oleksandr Glushchenko on 7/20/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import UIKit
extension UITextView {
var cursorOffset: Int? {
guard let range = selectedTextRange else { return nil }
return offset(from: beginningOfDocument, to: range.start)
}
var cursorIndex: String.Index? {
guard
let location = cursorOffset,
case let length = text.utf16.count-location
else { return nil }
return Range(.init(location: location, length: length), in: text)?.lowerBound
}
var cursorDistance: Int? {
guard let cursorIndex = cursorIndex else { return nil }
return text.distance(from: text.startIndex, to: cursorIndex)
}
public func getTextRange() -> UITextRange? {
if let start = position(from: self.beginningOfDocument, offset: self.selectedRange.location),
let end = position(from: start, offset: self.selectedRange.length),
let selectedRange = textRange(from: start, to: end) {
return selectedRange
}
return nil
}
public func insertAttributedText(_ attr: NSAttributedString) {
let range = self.selectedRange
undoManager?.beginUndoGrouping()
let old = textStorage.attributedSubstring(from: range)
let oldMutable = NSMutableAttributedString(attributedString: old)
oldMutable.saveData()
undoManager?.registerUndo(withTarget: self) { target in
target.replace(range: NSRange(location: range.location, length: attr.length), with: oldMutable)
}
undoManager?.setActionName("Insert")
textStorage.beginEditing()
textStorage.replaceCharacters(in: range, with: attr)
textStorage.endEditing()
selectedRange = NSRange(location: range.location + attr.length, length: 0)
undoManager?.endUndoGrouping()
delegate?.textViewDidChange?(self)
}
private func replace(range: NSRange, with attr: NSAttributedString) {
let old = textStorage.attributedSubstring(from: range)
let oldMutable = NSMutableAttributedString(attributedString: old)
oldMutable.saveData()
undoManager?.registerUndo(withTarget: self) { target in
target.replace(range: NSRange(location: range.location, length: attr.length), with: oldMutable)
}
textStorage.beginEditing()
textStorage.replaceCharacters(in: range, with: attr)
textStorage.endEditing()
selectedRange = NSRange(location: range.location + attr.length, length: 0)
delegate?.textViewDidChange?(self)
}
}
================================================
FILE: FSNotes iOS/Extensions/UserDefaultsManagement+.swift
================================================
//
// UserDefaultsManagement+.swift
// FSNotes
//
// Created by Oleksandr Glushchenko on 10/26/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import Foundation
import UIKit
extension UserDefaultsManagement {
private struct Constants {
static let appIcon = "appIcon2025"
static let currentNote = "currentNote"
static let currentLocation = "currentLocation"
static let currentLength = "currentLength"
static let dynamicTypeFont = "dynamicTypeFont"
static let editorAutocorrection = "editorAutocorrection"
static let editorState = "editorState"
static let editorSuggestions = "editorSuggestions"
static let ImportURLsKey = "ImportURLs"
}
static var appIcon: Int {
get {
if let theme = shared?.integer(forKey: Constants.appIcon) {
return theme
}
return 1
}
set {
shared?.set(newValue, forKey: Constants.appIcon)
}
}
static var dynamicTypeFont: Bool {
get {
if let result = shared?.object(forKey: Constants.dynamicTypeFont) as? Bool {
return result
}
return true
}
set {
shared?.set(newValue, forKey: Constants.dynamicTypeFont)
}
}
static var sidebarIsOpened: Bool {
get {
if let result = shared?.object(forKey: "sidebarIsOpened") as? Bool {
return result
}
return false
}
set {
shared?.set(newValue, forKey: "sidebarIsOpened")
}
}
static var editorAutocorrection: Bool {
get {
if let result = shared?.object(forKey: Constants.editorAutocorrection) as? Bool {
return result
}
return true
}
set {
shared?.set(newValue, forKey: Constants.editorAutocorrection)
}
}
static var editorSpellChecking: Bool {
get {
if let result = shared?.object(forKey: Constants.editorSuggestions) as? Bool {
return result
}
return true
}
set {
shared?.set(newValue, forKey: Constants.editorSuggestions)
}
}
static var currentNote: URL? {
get {
if let url = shared?.url(forKey: Constants.currentNote) {
return url
}
return nil
}
set {
shared?.set(newValue, forKey: Constants.currentNote)
}
}
static var currentRange: NSRange? {
get {
if let location = shared?.integer(forKey: Constants.currentLocation),
let length = shared?.integer(forKey: Constants.currentLength) {
return NSRange(location: location, length: length)
}
return nil
}
set {
if let range = newValue {
shared?.set(range.location, forKey: Constants.currentLocation)
shared?.set(range.length, forKey: Constants.currentLength)
} else {
shared?.set(nil, forKey: Constants.currentLocation)
shared?.set(nil, forKey: Constants.currentLength)
}
}
}
static var currentEditorState: Bool? {
get {
if let result = shared?.object(forKey: Constants.editorState) as? Bool {
return result
}
return nil
}
set {
shared?.set(newValue, forKey: Constants.editorState)
}
}
static var noteFont: UIFont {
get {
if #available(iOS 11.0, *), UserDefaultsManagement.dynamicTypeFont {
var font = UIFont.systemFont(ofSize: CGFloat(DefaultFontSize))
if let fontName = UserDefaultsManagement.fontName,
let currentFont = UIFont(name: fontName, size: CGFloat(DefaultFontSize)) {
font = currentFont
}
let fontMetrics = UIFontMetrics(forTextStyle: .body)
return fontMetrics.scaledFont(for: font)
}
if let name = self.fontName, name.starts(with: ".") {
return UIFont.systemFont(ofSize: CGFloat(self.fontSize))
}
if let fontName = self.fontName, let font = UIFont(name: fontName, size: CGFloat(self.fontSize)) {
return font
}
return UIFont.systemFont(ofSize: CGFloat(self.fontSize))
}
set {
self.fontName = newValue.fontName
self.fontSize = Int(newValue.pointSize)
}
}
static var codeFont: UIFont {
get {
if #available(iOS 11.0, *), UserDefaultsManagement.dynamicTypeFont {
var font = Font.systemFont(ofSize: CGFloat(self.codeFontSize))
if let currentFont = Font(name: self.codeFontName, size: CGFloat(self.codeFontSize)) {
font = currentFont
}
let fontMetrics = UIFontMetrics(forTextStyle: .body)
return fontMetrics.scaledFont(for: font)
}
if let font = UIFont(name: self.codeFontName, size: CGFloat(self.codeFontSize)) {
return font
}
return UIFont.systemFont(ofSize: CGFloat(self.codeFontSize))
}
set {
self.codeFontName = newValue.familyName
self.codeFontSize = Int(newValue.pointSize)
}
}
@available(iOS 11.0, *)
static var importURLs: [URL] {
get {
guard let defaults = UserDefaults.init(suiteName: "group.es.fsnot.user.defaults") else { return [] }
if let result = defaults.object(forKey: Constants.ImportURLsKey) as? Data,
let urls = NSArray.unsecureUnarchived(from: result) as? [URL] {
return urls
}
return []
}
set {
guard let defaults = UserDefaults.init(suiteName: "group.es.fsnot.user.defaults") else { return }
if let data = try? NSKeyedArchiver.archivedData(withRootObject: newValue, requiringSecureCoding: true) {
defaults.set(data, forKey: Constants.ImportURLsKey)
}
}
}
static var fontColor: Color {
get {
return self.DefaultFontColor
}
}
static var bgColor: Color {
get {
return self.DefaultBgColor
}
}
}
extension NSCoding where Self: NSObject {
@available(iOS 11.0, *)
static func unsecureUnarchived(from data: Data) -> Self? {
do {
let unarchiver = try NSKeyedUnarchiver(forReadingFrom: data)
unarchiver.requiresSecureCoding = true
let obj = unarchiver.decodeObject(of: self, forKey: NSKeyedArchiveRootObjectKey)
if let error = unarchiver.error {
print("Error:\(error)")
}
return obj
} catch {
print("Error:\(error)")
}
return nil
}
}
================================================
FILE: FSNotes iOS/FSNotes iOS.entitlements
================================================
aps-environment
development
com.apple.developer.icloud-container-environment
Production
com.apple.developer.icloud-container-identifiers
iCloud.co.fluder.fsnotes
com.apple.developer.icloud-services
CloudDocuments
com.apple.developer.ubiquity-container-identifiers
iCloud.co.fluder.fsnotes
com.apple.developer.ubiquity-kvstore-identifier
$(TeamIdentifierPrefix)co.fluder.fsnotes
com.apple.security.application-groups
group.es.fsnot.user.defaults
================================================
FILE: FSNotes iOS/FSNotes_iOS.xcdatamodeld/.xccurrentversion
================================================
================================================
FILE: FSNotes iOS/FSNotes_iOS.xcdatamodeld/FSNotes_iOS.xcdatamodel/contents
================================================
================================================
FILE: FSNotes iOS/Helpers/Buttons.swift
================================================
//
// Buttons.swift
// FSNotes iOS
//
// Created by Oleksandr Glushchenko on 9/20/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import UIKit
class Buttons {
public static func getRateUs(target: Any, selector: Selector) -> UIBarButtonItem {
return UIBarButtonItem(systemImageName: "heart", target: target, selector: selector)
}
public static func getAdd(target: Any, selector: Selector) -> UIBarButtonItem {
return UIBarButtonItem(systemImageName: "plus", target: target, selector: selector)
}
public static func getDone(target: Any, selector: Selector) -> UIBarButtonItem {
return UIBarButtonItem(title: NSLocalizedString("Done", comment: ""), style: .plain, target: target, action: selector)
}
public static func getShare(target: Any, selector: Selector) -> UIBarButtonItem {
return UIBarButtonItem(systemImageName: "square.and.arrow.up", target: target, selector: selector)
}
public static func getCrop(target: Any, selector: Selector) -> UIBarButtonItem {
return UIBarButtonItem(systemImageName: "crop", target: target, selector: selector)
}
public static func getTrash(target: Any, selector: Selector) -> UIBarButtonItem {
return UIBarButtonItem(systemImageName: "trash", target: target, selector: selector)
}
public static func getNewNote(target: Any, selector: Selector) -> UIBarButtonItem {
let config = UIImage.SymbolConfiguration(pointSize: 20, weight: .bold, scale: .default)
let image = UIImage(systemName: "square.and.pencil", withConfiguration: config)?
.imageWithColor(color1: UIColor.mainTheme)
let button = UIButton(type: .system)
button.setImage(image, for: .normal)
button.tintColor = .mainTheme
button.imageEdgeInsets = UIEdgeInsets(top: -2, left: 3, bottom: 2, right: -3)
button.addTarget(target, action: selector, for: .touchUpInside)
return UIBarButtonItem(customView: button)
}
}
================================================
FILE: FSNotes iOS/Helpers/CloudDriveManager.swift
================================================
//
// CloudDriveManager.swift
// FSNotes iOS
//
// Created by Oleksandr Glushchenko on 6/13/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import Foundation
import UIKit
class CloudDriveManager {
private var cloudDriveResults = [URL]()
private var delegate: ViewController
private var storage: Storage
public let metadataQuery = NSMetadataQuery()
private var resultsDict = NSMutableDictionary()
private let workerQueue: OperationQueue = {
let workerQueue = OperationQueue()
workerQueue.name = "co.fluder.fsnotes.manager.browserdatasource.workerQueue"
workerQueue.maxConcurrentOperationCount = 1
workerQueue.qualityOfService = .background
return workerQueue
}()
private var shouldLoadTags: Bool = false
private var notesInsertionQueue = [Note]()
private var notesDeletionQueue = [Note]()
private var notesModificationQueue = [Note]()
private var projectsInsertionQueue = [Project]()
private var projectsDeletionQueue = [Project]()
init(delegate: ViewController, storage: Storage) {
metadataQuery.operationQueue = workerQueue
metadataQuery.searchScopes = [
NSMetadataQueryUbiquitousDocumentsScope
]
metadataQuery.notificationBatchingInterval = 1
metadataQuery.predicate = NSPredicate(format: "%K LIKE '*'", NSMetadataItemFSNameKey)
metadataQuery.sortDescriptors = [NSSortDescriptor(key: NSMetadataItemFSContentChangeDateKey, ascending: false)]
self.delegate = delegate
self.storage = storage
}
@objc func queryDidFinishGathering(notification: NSNotification) {
let query = notification.object as? NSMetadataQuery
if let results = query?.results as? [NSMetadataItem] {
saveCloudDriveResultsCache(results: results)
startInitialLoading(results: results)
}
metadataQuery.enableUpdates()
}
@objc func handleMetadataQueryUpdates(notification: NSNotification) {
guard let metadataQuery = notification.object as? NSMetadataQuery else { return }
metadataQuery.disableUpdates()
let changed = change(notification: notification)
let added = added(notification: notification)
let removed = remove(notification: notification)
doVisualChanges()
if added > 0 || removed > 0 || changed > 0,
let results = metadataQuery.results as? [NSMetadataItem] {
saveCloudDriveResultsCache(results: results)
}
metadataQuery.enableUpdates()
}
private func saveCloudDriveResultsCache(results: [NSMetadataItem]) {
// let point = Date()
for result in results {
if let url = result.value(forAttribute: NSMetadataItemURLKey) as? URL {
resultsDict[metadataQuery.index(ofResult: result)] = url.standardized
}
}
// print("N. iCloud Drive resources: \"\(results.count)\", caching finished in \(point.timeIntervalSinceNow * -1) seconds.")
}
private func startInitialLoading(results: [NSMetadataItem]) {
for metadataItem in results {
let url = metadataItem.value(forAttribute: NSMetadataItemURLKey) as? URL
let status = metadataItem.value(forAttribute: NSMetadataUbiquitousItemDownloadingStatusKey) as? String
if status == NSMetadataUbiquitousItemDownloadingStatusNotDownloaded,
let url = url,
FileManager.default.isUbiquitousItem(at: url) {
do {
try FileManager.default.startDownloadingUbiquitousItem(at: url)
} catch {
print("Download error: \(error)")
}
}
}
}
private func isProject(item: NSMetadataItem) -> Bool {
let itemUrl = item.value(forAttribute: NSMetadataItemURLKey) as? URL
let isDirectory = (item.value(forAttribute: NSMetadataItemContentTypeKey) as? String) == "public.folder"
let isPackage = (try? itemUrl?.resourceValues(forKeys: [.isDirectoryKey]))?.isPackage ?? false
guard let url = itemUrl?.standardized else { return false }
return isDirectory && !isPackage && url.pathExtension != "textbundle"
}
private func change(notification: NSNotification) -> Int {
guard let changedMetadataItems = notification.userInfo?[NSMetadataQueryUpdateChangedItemsKey] as? [NSMetadataItem] else { return 0 }
var completed = 0
for item in changedMetadataItems {
let status = item.value(forAttribute: NSMetadataUbiquitousItemDownloadingStatusKey) as? String
let index = metadataQuery.index(ofResult: item)
let itemUrl = item.value(forAttribute: NSMetadataItemURLKey) as? URL
let contentChangeDate = item.value(forAttribute: NSMetadataItemFSContentChangeDateKey) as? Date
let creationDate = item.value(forAttribute: NSMetadataItemFSCreationDateKey) as? Date
if status == NSMetadataUbiquitousItemDownloadingStatusCurrent {
completed += 1
}
guard let url = itemUrl?.standardized, status == NSMetadataUbiquitousItemDownloadingStatusCurrent else {
continue
}
if isProject(item: item) {
// Renamed – remove old
if let project = getProjectFromCloudDriveResults(item: item) {
// Remove old
projectsDeletionQueue.append(project)
// Insert new
if let projects = storage.insert(url: url) {
projectsInsertionQueue.append(contentsOf: projects)
}
} else {
// Move from outside iCloud Drive
if storage.getProjectBy(url: url) == nil {
if let projects = storage.insert(url: url) {
projectsInsertionQueue.append(contentsOf: projects)
}
}
}
continue
}
if url.lastPathComponent == ".encrypt" {
self.loadEncryptionStatus(url: url)
continue
}
// Is file
guard storage.isValidNote(url: url) else { continue }
// Note already exist and update completed
if let note = storage.getBy(url: url, caseSensitive: true) {
if note.isTextBundle() && !note.isFullLoadedTextBundle() {
continue
}
let modificationDate = note.getFileModifiedDate()
let isOpened = delegate.editorViewController?.editArea.note?.isEqualURL(url: url) == true
if let modificationDate = modificationDate,
let contentChangeDate = contentChangeDate,
isOpened,
modificationDate.isGreaterThan(note.modifiedLocalAt),
contentChangeDate.isGreaterThan(note.modifiedLocalAt)
{
let prepareDate =
modificationDate > contentChangeDate
? modificationDate
: contentChangeDate
if prepareDate > note.modifiedLocalAt {
note.modifiedLocalAt = prepareDate
}
// Trying load content from encrypted note with current password
if url.pathExtension == "etp", let password = note.password {
_ = note.unLock(password: password)
}
note.forceLoad()
delegate.refreshTextStorage(note: note)
}
// print("File changed: \(url)")
// Not updates in FS attributes, must be loaded from Cloud Drive Meta
if note.isTextBundle() {
note.loadCreationDate()
} else {
note.creationDate = creationDate
}
notesModificationQueue.append(note)
//resolveConflict(url: url)
continue
}
// Note previously exist on different path
if let note = getNoteFromCloudDriveResults(item: item) {
// moved to unavailable dir (i.e. trash) is equal removed
guard storage.getProjectByNote(url: url) != nil else {
storage.removeNotes(notes: [note], fsRemove: false) {_ in
self.notesDeletionQueue.append(note)
}
print("File moved outside: \(url)")
continue
}
// moved to available dir
print("File moved to new url: \(url)")
notesDeletionQueue.append(note)
let srcUrl = note.url
note.url = url
note.parseURL()
note.moveHistory(src: srcUrl, dst: url)
resultsDict[index] = url
notesInsertionQueue.append(note)
continue
}
// Non exist yet, will add
if let note = storage.importNote(url: url) {
notesInsertionQueue.append(note)
}
}
return completed
}
private func getNoteFromCloudDriveResults(item: NSMetadataItem) -> Note? {
let itemUrl = item.value(forAttribute: NSMetadataItemURLKey) as? URL
guard let url = itemUrl?.standardized else { return nil }
let index = self.metadataQuery.index(ofResult: item)
guard let prev = resultsDict[index] as? URL else { return nil }
if prev != url {
if let note = storage.getBy(url: prev) {
return note
}
}
return nil
}
private func getProjectFromCloudDriveResults(item: NSMetadataItem) -> Project? {
let itemUrl = item.value(forAttribute: NSMetadataItemURLKey) as? URL
guard let url = itemUrl?.standardized else { return nil }
let index = self.metadataQuery.index(ofResult: item)
guard let prev = resultsDict[index] as? URL else { return nil }
if prev != url {
if let project = storage.getProjectBy(url: prev) {
return project
}
}
return nil
}
private func added(notification: NSNotification) -> Int {
guard let addedMetadataItems =
notification.userInfo?[NSMetadataQueryUpdateAddedItemsKey] as? [NSMetadataItem]
else { return 0 }
for item in addedMetadataItems {
guard let url = (item.value(forAttribute: NSMetadataItemURLKey) as? URL)?.standardized else { continue }
print("Added: \(url)")
let status = item.value(forAttribute: NSMetadataUbiquitousItemDownloadingStatusKey) as? String
if status != NSMetadataUbiquitousItemDownloadingStatusCurrent
&& FileManager.default.isUbiquitousItem(at: url) {
do {
try FileManager.default.startDownloadingUbiquitousItem(at: url)
} catch {
print("Download error: \(error)")
}
continue
}
if isProject(item: item) {
if let projects = storage.insert(url: url) {
projectsInsertionQueue.append(contentsOf: projects)
}
continue
}
// when file moved from outspace to FSNotes space
// i.e. revert from macOS trash to iCloud Drive
if storage.isValidNote(url: url) {
if let note = storage.importNote(url: url) {
notesInsertionQueue.append(note)
}
}
}
return addedMetadataItems.count
}
private func remove(notification: NSNotification) -> Int {
guard let removedMetadataItems =
notification.userInfo?[NSMetadataQueryUpdateRemovedItemsKey] as?
[NSMetadataItem]
else { return 0 }
for item in removedMetadataItems {
guard let url = (item.value(forAttribute: NSMetadataItemURLKey) as? URL)?.standardized else { continue }
if isProject(item: item) {
if let project = storage.getProjectBy(url: url) {
projectsDeletionQueue.append(contentsOf: [project])
}
continue
}
if url.lastPathComponent == ".encrypt" {
self.loadEncryptionStatus(url: url)
continue
}
if FileManager.default.fileExists(atPath: url.path) {
continue
}
if let note = storage.getBy(url: url) {
storage.removeNotes(notes: [note], fsRemove: false) {_ in
self.notesDeletionQueue.append(note)
}
}
if let project = storage.getProjectBy(url: url) {
storage.remove(project: project)
self.projectsDeletionQueue.append(project)
}
}
return removedMetadataItems.count
}
private func loadEncryptionStatus(url: URL) {
if let project = self.storage.getProjectBy(url: url.deletingLastPathComponent()) {
let state = project.isEncrypted
project.isEncrypted = FileManager.default.fileExists(atPath: url.path)
if state && !project.isEncrypted {
project.password = nil
}
DispatchQueue.main.async {
if let indexPath = self.delegate.sidebarTableView.getIndexPathBy(project: project) {
if let sidebarItem = self.delegate.sidebarTableView.getSidebarItem(project: project) {
var type: SidebarItemType = .Project
if project.isEncrypted {
if project.isLocked() {
type = .ProjectEncryptedLocked
} else {
type = .ProjectEncryptedUnlocked
}
}
sidebarItem.setType(type: type)
let cell = self.delegate.sidebarTableView.cellForRow(at: indexPath) as? SidebarTableCellView
cell?.configure(sidebarItem: sidebarItem)
}
self.delegate.sidebarTableView.reload(indexPath: indexPath)
// Selected at this moment
if indexPath == self.delegate.sidebarTableView.indexPathForSelectedRow {
if project.isEncrypted && project.isLocked() {
self.delegate.enableLockedProject()
} else {
self.delegate.disableLockedProject()
}
self.delegate.reloadNotesTable()
// Reconfigure new state in menu
if let sidebarItem = self.delegate.sidebarTableView.getSidebarItem(project: project) {
self.delegate.configureNavMenu(for: sidebarItem)
}
}
}
}
}
}
public func resolveConflict(url: URL) {
if let conflicts = NSFileVersion.unresolvedConflictVersionsOfItem(at: url as URL) {
for conflict in conflicts {
guard let modificationDate = conflict.modificationDate else {
continue
}
guard let localizedName = conflict.localizedName else {
continue
}
let localizedUrl = URL(fileURLWithPath: localizedName)
let ext = url.pathExtension
let name = localizedUrl.deletingPathExtension().lastPathComponent
let dateFormatter = ISO8601DateFormatter()
dateFormatter.formatOptions = [
.withYear,
.withMonth,
.withDay,
.withTime
]
let dateString: String = dateFormatter.string(from: modificationDate)
let conflictName = "\(name) (CONFLICT \(dateString)).\(ext)"
let to = url.deletingLastPathComponent().appendingPathComponent(conflictName)
if FileManager.default.fileExists(atPath: to.path) {
conflict.isResolved = true
continue
}
// Reload current encrypted note
if let currentNote = delegate.editorViewController?.editArea.note, currentNote.url == url {
if let password = currentNote.password, ext == "etp" {
_ = currentNote.unLock(password: password)
}
currentNote.forceLoad()
delegate.refreshTextStorage(note: currentNote)
}
do {
try FileManager.default.copyItem(at: conflict.url, to: to)
var attributes = [FileAttributeKey : Any]()
attributes[.posixPermissions] = 0o777
try FileManager.default.setAttributes(attributes, ofItemAtPath: to.path)
} catch let error {
print("Conflict resolving error: ", error)
}
conflict.isResolved = true
}
}
}
private func doVisualChanges() {
let insert = notesInsertionQueue
let delete = notesDeletionQueue
let change = notesModificationQueue
notesInsertionQueue.removeAll()
notesDeletionQueue.removeAll()
notesModificationQueue.removeAll()
let projectsDeletion = projectsDeletionQueue
let projectsInsertion = projectsInsertionQueue
projectsDeletionQueue.removeAll()
projectsInsertionQueue.removeAll()
for note in insert {
note.forceLoad(skipCreateDate: false, loadTags: false)
}
for note in change {
note.forceLoad(skipCreateDate: true, loadTags: false)
}
OperationQueue.main.addOperation {
self.delegate.notesTable.removeRows(notes: delete)
self.delegate.notesTable.insertRows(notes: insert)
self.delegate.notesTable.reloadRows(notes: change)
self.delegate.sidebarTableView.removeRows(projects: projectsDeletion)
self.delegate.sidebarTableView.insertRows(projects: projectsInsertion)
self.delegate.updateNotesCounter()
}
}
}
================================================
FILE: FSNotes iOS/Helpers/FolderPopoverActions.swift
================================================
//
// FolderPopoverActions.swift
// FSNotes iOS
//
// Created by Александр on 27.01.2022.
// Copyright © 2022 Oleksandr Glushchenko. All rights reserved.
//
import Foundation
enum FolderPopoverActions: Int {
case importNote
case multipleSelection
case settingsFolder
case settingsRepository
case createFolder
case removeFolder
case renameFolder
case removeTag
case renameTag
case openInFiles
case emptyBin
case encryptFolder
case decryptFolder
case lockFolder
case unLockFolder
static let description =
[
NSLocalizedString("Import Notes", comment: "Main view popover table"),
NSLocalizedString("Select", comment: "Main view popover table"),
NSLocalizedString("View Settings", comment: "Main view popover table"),
NSLocalizedString("Git Settings", comment: "Main view popover table"),
NSLocalizedString("Create Folder", comment: "Main view popover table"),
NSLocalizedString("Remove Folder", comment: "Main view popover table"),
NSLocalizedString("Rename Folder", comment: "Main view popover table"),
NSLocalizedString("Remove Tag", comment: "Main view popover table"),
NSLocalizedString("Rename Tag", comment: "Main view popover table"),
NSLocalizedString("Open in Files.app", comment: "Main view popover table"),
NSLocalizedString("Empty Bin", comment: "Main view popover table"),
NSLocalizedString("Encrypt", comment: "Main view popover table"),
NSLocalizedString("Decrypt", comment: "Main view popover table"),
NSLocalizedString("Lock", comment: "Main view popover table"),
NSLocalizedString("Unlock", comment: "Main view popover table"),
]
public func getDescription() -> String {
return FolderPopoverActions.description[self.rawValue]
}
}
================================================
FILE: FSNotes iOS/Helpers/SandboxBookmark.swift
================================================
//
// SandboxBookmarks.swift
// FSNotes
//
// Created by Олександр Глущенко on 7/28/19.
// Copyright © 2019 Oleksandr Glushchenko. All rights reserved.
//
import Foundation
class SandboxBookmark {
static var instance: SandboxBookmark? = nil
private let bookmarksKey = "SecurityBookmarksKey"
private var defaults = UserDefaults.init(suiteName: "group.es.fsnot.user.defaults")
private var bookmarks = [URL: Data]()
public static func sharedInstance() -> SandboxBookmark {
guard let sandbox = self.instance else {
self.instance = SandboxBookmark()
return self.instance!
}
return sandbox
}
public func load() {
if let bookmarks = defaults?.object(forKey: bookmarksKey) as? [Data] {
for bookmarkData in bookmarks {
do {
var isStale = false
let url = try URL(resolvingBookmarkData: bookmarkData, bookmarkDataIsStale: &isStale)
if !isStale {
if url.startAccessingSecurityScopedResource() {
self.bookmarks[url.standardized] = bookmarkData
print("URL loaded from security scope: \(url)")
}
} else {
remove(url: url)
}
}
catch let error {
print(error)
}
}
}
}
public func save(data: Data) {
var bookmarks = [Data]()
if let bookmarksData = defaults?.object(forKey: bookmarksKey) as? [Data] {
bookmarks = bookmarksData
}
bookmarks.append(data)
save(data: bookmarks)
}
public func save(data: [Data]) {
defaults?.set(data, forKey: bookmarksKey)
defaults?.synchronize()
}
public func remove(url: URL) {
self.bookmarks.removeValue(forKey: url)
// old style bookmarks
let oldStylePath = "/private" + url.path
if let index = bookmarks.firstIndex(where: { $0.key.path == oldStylePath }) {
bookmarks.remove(at: index)
}
let values = bookmarks.map({ $0.value })
save(data: values)
}
public func getRestoredUrls() -> [URL] {
return bookmarks.map({ $0.key })
}
}
================================================
FILE: FSNotes iOS/Helpers/ShortcutIdentifier.swift
================================================
//
// ShortcutIdentifier.swift
// FSNotes iOS
//
// Created by Oleksandr Glushchenko on 9/15/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import Foundation
enum ShortcutIdentifier: String {
case makeNew
case search
case clipboard
// MARK: - Initializers
init?(fullType: String) {
guard let last = fullType.components(separatedBy: ".").last else { return nil }
self.init(rawValue: last)
}
// MARK: - Properties
var type: String {
return Bundle.main.bundleIdentifier! + ".\(self.rawValue)"
}
}
================================================
FILE: FSNotes iOS/Helpers/Sidebar.swift
================================================
//
// Sideabr.swift
// FSNotes iOS
//
// Created by Олександр Глущенко on 02.11.2019.
// Copyright © 2019 Oleksandr Glushchenko. All rights reserved.
//
import UIKit
typealias Image = UIImage
enum SidebarSection: Int {
case System = 0x00
case Projects = 0x01
case Tags = 0x02
case Settings = 0x03
}
class Sidebar {
let storage = Storage.shared()
public var items = [[SidebarItem]]()
public var allItems = [[SidebarItem]]()
init() {
guard let defaultURL = Storage.shared().getDefault()?.url else { return }
var system = [SidebarItem]()
// Notes
let notesUrl = defaultURL.appendingPathComponent("Fake Virtual Notes Dir")
let notesLabel = NSLocalizedString("Notes", comment: "Sidebar items")
if UserDefaultsManagement.sidebarVisibilityNotes {
let fakeNotesProject =
Project(
storage: Storage.shared(),
url: notesUrl,
label: notesLabel,
isVirtual: true
)
Storage.shared().allNotesProject = fakeNotesProject
system.append(
SidebarItem(
name: NSLocalizedString("Notes", comment: ""),
project: fakeNotesProject,
type: .All
)
)
}
// Inbox
if UserDefaultsManagement.sidebarVisibilityInbox,
let project = Storage.shared().getDefault() {
system.append(
SidebarItem(
name: NSLocalizedString("Inbox", comment: ""),
project: project,
type: .Inbox
)
)
}
// Todo
if UserDefaultsManagement.sidebarVisibilityTodo {
let todoUrl = defaultURL.appendingPathComponent("Fake Virtual Todo Dir")
let todoLabel = NSLocalizedString("Todo", comment: "Sidebar items")
let fakeTodoProject =
Project(
storage: Storage.shared(),
url: todoUrl,
label: todoLabel,
isVirtual: true
)
system.append(
SidebarItem(
name: NSLocalizedString("Todo", comment: ""),
project: fakeTodoProject,
type: .Todo
)
)
Storage.shared().todoProject = fakeTodoProject
}
// Untagged
if UserDefaultsManagement.sidebarVisibilityUntagged {
let todoUrl = defaultURL.appendingPathComponent("Fake Virtual Utagged Dir")
let untaggedLabel = NSLocalizedString("Untagged", comment: "")
let fakeUntaggedProject =
Project(
storage: Storage.shared(),
url: todoUrl,
label: untaggedLabel,
isVirtual: true
)
let untagged =
SidebarItem(
name: untaggedLabel,
project: fakeUntaggedProject,
type: .Untagged
)
system.append(untagged)
}
// Trash
if UserDefaultsManagement.sidebarVisibilityTrash {
system.append(
SidebarItem(
name: NSLocalizedString("Trash", comment: ""),
project: Storage.shared().getDefaultTrash(),
type: .Trash
)
)
}
// System - section 0
items.append(system)
// Projects - section 1
let projects = storage
.getAvailableProjects()
.sorted(by: { $0.label < $1.label })
.map({
SidebarItem(
name: $0.label,
project: $0,
type: .Project
)
})
items.append(projects)
// Tags - section 2
items.append([])
}
}
================================================
FILE: FSNotes iOS/Helpers/SingleImageTouchDownGestureRecognizer.swift
================================================
//
// SingleImageTouchDownGestureRecognizer.swift
// FSNotes iOS
//
// Created by Олександр Глущенко on 8/17/19.
// Copyright © 2019 Oleksandr Glushchenko. All rights reserved.
//
import UIKit.UIGestureRecognizerSubclass
class SingleImageTouchDownGestureRecognizer: UIGestureRecognizer {
public var isRightBorderTap = false
override func touchesBegan(_ touches: Set, with event: UIEvent) {
if touches.count > 1 {
self.state = .failed
}
if self.state == .possible {
for touch in touches {
guard let view = self.view as? EditTextView else { continue }
let point = touch.location(in: view)
let glyphIndex = view.layoutManager.glyphIndex(for: point, in: view.textContainer)
let location = touch.location(in: view)
let maxX = Int(view.frame.width - 50)
let minX = Int(50)
let isImage = view.isImage(at: glyphIndex)
let glyphRect = view.layoutManager.boundingRect(forGlyphRange: NSRange(location: glyphIndex, length: 1), in: view.textContainer)
if Int(location.x) < minX || Int(location.x) > maxX, isImage, glyphIndex < view.textStorage.length, glyphRect.contains(point) {
self.state = .possible
isRightBorderTap = Int(location.x) > maxX
} else {
self.state = .failed
}
}
}
}
override func touchesEnded(_ touches: Set, with event: UIEvent) {
if self.state == .possible {
for touch in touches {
guard let view = self.view as? EditTextView else { continue }
let point = touch.location(in: view)
let glyphIndex = view.layoutManager.glyphIndex(for: point, in: view.textContainer)
let location = touch.location(in: view)
let maxX = Int(view.frame.width - 25)
let minX = Int(25)
let isImage = view.isImage(at: glyphIndex)
let glyphRect = view.layoutManager.boundingRect(forGlyphRange: NSRange(location: glyphIndex, length: 1), in: view.textContainer)
if Int(location.x) < minX || Int(location.x) > maxX, isImage, glyphIndex < view.textStorage.length, glyphRect.contains(point) {
self.state = .recognized
} else {
self.state = .failed
}
}
}
}
}
================================================
FILE: FSNotes iOS/Helpers/SingleTouchDownGestureRecognizer.swift
================================================
//
// SingleTouchDownGestureRecognizer.swift
// FSNotes iOS
//
// Created by Oleksandr Glushchenko on 8/30/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import UIKit.UIGestureRecognizerSubclass
class SingleTouchDownGestureRecognizer: UIGestureRecognizer {
private var beginTimer: Timer?
private var beginTime: Date?
public var isLongPress: Bool = false
public var touchCharIndex: Int?
public var selectedRange: UITextRange?
override func touchesBegan(_ touches: Set, with event: UIEvent) {
guard let view = self.view as? EditTextView else { return }
self.selectedRange = view.selectedTextRange
view.isAllowedScrollRect = false
if touches.count > 1 {
self.state = .failed
view.isAllowedScrollRect = true
return
}
if self.state == .possible {
for touch in touches {
let point = touch.location(in: view)
let characterIndex = view.layoutManager.characterIndex(for: point, in: view.textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
self.touchCharIndex = characterIndex
if UIMenuController.shared.isMenuVisible {
UIMenuController.shared.hideMenu(from: view)
}
let glyphIndex = view.layoutManager.glyphIndex(for: point, in: view.textContainer)
if isTodoInTouchArea(point: point, characterIndex: characterIndex, view: view) && (self.selectedRange?.isEmpty == true || !view.isFirstResponder) {
self.state = .recognized
return
}
let maxX = Int(view.frame.width - 50)
let minX = Int(50)
let isImage = view.isImage(at: characterIndex)
let glyphRect = view.layoutManager.boundingRect(forGlyphRange: NSRange(location: glyphIndex, length: 1), in: view.textContainer)
if isImage, characterIndex < view.textStorage.length, glyphRect.contains(point) {
if Int(point.x) > minX && Int(point.x) < maxX {
view.lasTouchPoint = touch.location(in: view.superview)
self.state = .possible
view.isAllowedScrollRect = true
return
} else {
self.state = .failed
view.isAllowedScrollRect = true
return
}
}
if !isImage && glyphRect.contains(point) && view.isLink(at: characterIndex) {
self.state = .possible
view.isAllowedScrollRect = true
return
}
}
self.state = .failed
view.isAllowedScrollRect = true
}
}
private func isTodoInTouchArea(point: CGPoint, characterIndex: Int, view: EditTextView) -> Bool {
if view.isTodo(at: characterIndex) {
return true
}
func checkTodoInLine(lineRange: NSRange) -> Bool {
for i in lineRange.location.. 0 {
let previousLineRange = (view.text as NSString).lineRange(for: NSRange(location: currentLineRange.location - 1, length: 0))
if checkTodoInLine(lineRange: previousLineRange) {
return true
}
}
return false
}
override func touchesEnded(_ touches: Set, with event: UIEvent) {
guard let view = self.view as? EditTextView else { return }
if self.state == .possible {
for touch in touches {
let point = touch.location(in: view)
let characterIndex = view.layoutManager.characterIndex(for: point, in: view.textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
self.touchCharIndex = characterIndex
if view.isImage(at: characterIndex) {
self.state = .recognized
view.isAllowedScrollRect = true
return
}
if isTodoInTouchArea(point: point, characterIndex: characterIndex, view: view) {
self.state = .recognized
return
}
let glyphRect = view.layoutManager.boundingRect(forGlyphRange: NSRange(location: characterIndex, length: 1), in: view.textContainer)
if glyphRect.contains(point) && view.isLink(at: characterIndex) {
self.state = .recognized
view.isAllowedScrollRect = true
return
}
}
self.state = .failed
view.isAllowedScrollRect = true
}
}
}
================================================
FILE: FSNotes iOS/Icons/classic-2025.icon/icon.json
================================================
{
"fill" : {
"automatic-gradient" : "extended-gray:1.00000,1.00000"
},
"groups" : [
{
"layers" : [
{
"fill" : {
"automatic-gradient" : "srgb:0.00000,0.74277,1.00000,1.00000"
},
"image-name" : "Untitled-15.svg",
"name" : "row1",
"position" : {
"scale" : 1,
"translation-in-points" : [
-153.79487500000016,
157.33406250000007
]
}
},
{
"fill" : {
"automatic-gradient" : "srgb:0.00000,0.27616,1.00000,1.00000"
},
"image-name" : "Untitled-14.svg",
"name" : "row2",
"position" : {
"scale" : 1,
"translation-in-points" : [
-248.06381250000013,
32.89393749999999
]
}
},
{
"fill" : {
"automatic-gradient" : "srgb:0.00000,0.27616,1.00000,1.00000"
},
"image-name" : "Untitled-13.svg",
"name" : "row3",
"position" : {
"scale" : 1,
"translation-in-points" : [
-196.13787500000012,
-69.6507187499999
]
}
},
{
"fill" : {
"automatic-gradient" : "srgb:0.00000,0.27616,1.00000,1.00000"
},
"image-name" : "Untitled-12.svg",
"name" : "row4",
"position" : {
"scale" : 1,
"translation-in-points" : [
-149.16081250000013,
-181.203125
]
}
},
{
"fill" : {
"automatic-gradient" : "srgb:0.00000,0.74277,1.00000,1.00000"
},
"image-name" : "Untitled-8.svg",
"name" : "row5",
"position" : {
"scale" : 1,
"translation-in-points" : [
-7.970875000000149,
54.2109375
]
}
},
{
"fill" : {
"automatic-gradient" : "srgb:0.00000,0.27451,1.00000,1.00000"
},
"image-name" : "Untitled-11.svg",
"name" : "lightning",
"position" : {
"scale" : 2,
"translation-in-points" : [
172.49609375,
-35.471000000000004
]
}
}
],
"shadow" : {
"kind" : "neutral",
"opacity" : 0.5
},
"translucency" : {
"enabled" : true,
"value" : 0.5
}
}
],
"supported-platforms" : {
"circles" : [
"watchOS"
],
"squares" : "shared"
}
}
================================================
FILE: FSNotes iOS/Icons/modern.icon/icon.json
================================================
{
"fill" : "automatic",
"groups" : [
{
"layers" : [
{
"fill-specializations" : [
{
"value" : {
"automatic-gradient" : "srgb:0.11674,0.11137,0.12082,1.00000"
}
},
{
"appearance" : "dark",
"value" : {
"automatic-gradient" : "srgb:0.85953,0.87116,0.86212,1.00000"
}
}
],
"image-name" : "Untitled-5.svg",
"name" : "row1",
"position" : {
"scale" : 1,
"translation-in-points" : [
-76.92312500000003,
-199.8671875
]
}
},
{
"fill-specializations" : [
{
"value" : {
"automatic-gradient" : "srgb:0.11674,0.11137,0.12082,1.00000"
}
},
{
"appearance" : "dark",
"value" : {
"automatic-gradient" : "srgb:0.85953,0.87116,0.86212,1.00000"
}
}
],
"image-name" : "Untitled-2 3.svg",
"name" : "row2",
"position" : {
"scale" : 1,
"translation-in-points" : [
-136.953125,
-51.15625
]
}
},
{
"fill-specializations" : [
{
"value" : {
"automatic-gradient" : "srgb:0.11674,0.11137,0.12082,1.00000"
}
},
{
"appearance" : "dark",
"value" : {
"automatic-gradient" : "srgb:0.85953,0.87116,0.86212,1.00000"
}
}
],
"image-name" : "Untitled-3 2.svg",
"name" : "row3",
"position" : {
"scale" : 1,
"translation-in-points" : [
-199.593125,
98.390625
]
}
},
{
"fill" : {
"solid" : "display-p3:0.02353,0.56863,1.00000,1.00000"
},
"image-name" : "Untitled-3 2.svg",
"name" : "row4",
"position" : {
"scale" : 1,
"translation-in-points" : [
200.44268750000003,
-51.15625
]
}
},
{
"fill" : {
"solid" : "display-p3:0.02353,0.56863,1.00000,1.00000"
},
"image-name" : "Untitled-2 3.svg",
"name" : "row5",
"position" : {
"scale" : 1,
"translation-in-points" : [
137.8046875,
98.390625
]
}
},
{
"fill" : {
"solid" : "display-p3:0.02353,0.56863,1.00000,1.00000"
},
"glass" : true,
"image-name" : "Untitled-3 2.svg",
"name" : "row6",
"position" : {
"scale" : 1,
"translation-in-points" : [
75.16468750000001,
247.140625
]
}
}
],
"shadow" : {
"kind" : "neutral",
"opacity" : 0.5
},
"translucency" : {
"enabled" : true,
"value" : 0.5
}
}
],
"supported-platforms" : {
"circles" : [
"watchOS"
],
"squares" : "shared"
}
}
================================================
FILE: FSNotes iOS/Icons/ny-2026.icon/icon.json
================================================
{
"fill" : {
"linear-gradient" : [
"extended-srgb:0.68627,0.32157,0.87059,1.00000",
"display-p3:0.00000,0.66275,0.87843,1.00000"
],
"orientation" : {
"start" : {
"x" : 0.5,
"y" : 0
},
"stop" : {
"x" : 0.5,
"y" : 0.7
}
}
},
"groups" : [
{
"layers" : [
{
"fill" : {
"automatic-gradient" : "extended-gray:1.00000,1.00000"
},
"image-name" : "document-lightning-24-regular.svg",
"name" : "document-lightning-24-regular",
"opacity" : 0.9,
"position-specializations" : [
{
"idiom" : "square",
"value" : {
"scale" : 1.4,
"translation-in-points" : [
23.2528076171875,
-6.20391845703125
]
}
}
]
}
],
"shadow" : {
"kind" : "neutral",
"opacity" : 0.5
},
"translucency" : {
"enabled" : true,
"value" : 0.5
}
}
],
"supported-platforms" : {
"squares" : "shared"
}
}
================================================
FILE: FSNotes iOS/ImagePreviewViewController.swift
================================================
//
// ViewController.swift
// ImageScrollViewDemo
//
// Created by Nguyen Cong Huy on 3/5/16.
// Copyright © 2016 Nguyen Cong Huy. All rights reserved.
//
import UIKit
import AudioToolbox
import CropViewController
class ImagePreviewViewController: UIViewController, CropViewControllerDelegate {
@IBOutlet weak var imageScrollView: ImageScrollView!
public var image: UIImage?
public var url: URL?
public var note: Note?
public var imageUrls = [URL]()
private var currentIndex = 0
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(rotated), name: UIDevice.orientationDidChangeNotification, object: nil)
let shareButton = Buttons.getShare(target: self, selector: #selector(share))
let cropButton = Buttons.getCrop(target: self, selector: #selector(crop))
let dropButton = Buttons.getTrash(target: self, selector: #selector(trashBin))
let space = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)
space.width = 30
let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
toolbarItems = [flexibleSpace, shareButton, space, cropButton, space, dropButton]
navigationController?.setToolbarHidden(false, animated: true)
DispatchQueue.main.async {
self.rotated()
}
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(tapGestureRecognizer(_:)))
tapGesture.numberOfTapsRequired = 1
imageScrollView.addGestureRecognizer(tapGesture)
var urls = [URL]()
if let result = note?.content.getImagesAndFiles() {
for item in result {
urls.append(item.url)
}
}
imageUrls = urls
if let url = url, let index = imageUrls.firstIndex(of: url) {
currentIndex = index
}
}
@objc public func tapGestureRecognizer(_ gestureRecognizer: UIGestureRecognizer) {
let center = gestureRecognizer.location(in: gestureRecognizer.view)
var selectedUrl: URL?
if let zoomView = imageScrollView.zoomView, zoomView.frame.width > view.frame.width {
return
}
if center.x < 40 {
selectedUrl = prevImage()
}
if center.x > imageScrollView.frame.width - 40 {
selectedUrl = nextImage()
}
if let url = selectedUrl, let data = try? Data(contentsOf: url), let image = UIImage(data: data) {
imageScrollView.display(image: image)
self.image = image
self.url = selectedUrl
}
}
private func nextImage() -> URL {
currentIndex += 1
if currentIndex >= imageUrls.count {
currentIndex = 0
}
return imageUrls[currentIndex]
}
private func prevImage() -> URL {
currentIndex -= 1
if currentIndex < 0 {
currentIndex = imageUrls.count - 1
}
return imageUrls[currentIndex]
}
@IBAction func share() {
guard let url = self.url else { return }
AudioServicesPlaySystemSound(1519)
let objectsToShare = [url] as [Any]
let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
activityVC.excludedActivityTypes = [UIActivity.ActivityType.addToReadingList]
if UIDevice.current.userInterfaceIdiom == .pad {
guard let popOver = activityVC.popoverPresentationController else { return }
popOver.permittedArrowDirections = .down
popOver.sourceView = view
popOver.sourceRect = CGRect(x: view.bounds.midX, y: view.bounds.midY, width: 0, height: 0)
}
present(activityVC, animated: true, completion: nil)
}
@IBAction func done() {
dismiss(animated: true, completion: nil)
}
@IBAction func crop() {
guard let image = image else { return }
let cropViewController = CropViewController(image: image)
cropViewController.delegate = self
cropViewController.hidesNavigationBar = false
cropViewController.modalPresentationStyle = .fullScreen
cropViewController.modalTransitionStyle = .crossDissolve
cropViewController.transitioningDelegate = nil
present(cropViewController, animated: true, completion: nil)
}
@IBAction func trashBin() {
let messageText = NSLocalizedString("Are you sure you want to delete this image?", comment: "")
let alertController = UIAlertController(title: NSLocalizedString("Picture removing", comment: ""), message: messageText, preferredStyle: .alert)
let confirmAction = UIAlertAction(title: "OK", style: .default) { (_) in
if let url = self.url, let _ = self.note, let textView = UIApplication.getEVC().editArea {
if let imageRange = textView.textStorage.getImageRange(url: url) {
textView.selectedRange = imageRange
if let should = textView.delegate?.textView?(textView, shouldChangeTextIn: imageRange, replacementText: "") {
guard should else { return }
}
textView.insertAttributedText(NSAttributedString(string: ""))
}
}
self.navigationController?.popViewController(animated: true)
}
let cancelAction = UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .cancel) { (_) in }
alertController.addAction(confirmAction)
alertController.addAction(cancelAction)
self.present(alertController, animated: true, completion: nil)
}
@objc func rotated() {
imageScrollView.setup()
imageScrollView.imageContentMode = .aspectFit
imageScrollView.initialOffset = .center
imageScrollView.display(image: image!)
}
func cropViewController(_ cropViewController: CropViewController, didCropToImage image: UIImage, withRect cropRect: CGRect, angle: Int) {
if let url = url {
try? image.jpegData(compressionQuality: 0.6)?.write(to: url)
let cacheImage = NoteAttachment.getCacheUrl(from: url, prefix: "ThumbnailsBigInline")
if let path = cacheImage?.path, FileManager.default.fileExists(atPath: path) {
try? FileManager.default.removeItem(at: cacheImage!)
}
UIApplication.getEVC().refill()
}
self.imageScrollView.display(image: image)
if let windowScene = UIApplication.shared.connectedScenes
.filter({ $0.activationState == .foregroundActive })
.compactMap({ $0 as? UIWindowScene })
.first,
let rootViewController = windowScene.windows.first(where: { $0.isKeyWindow })?.rootViewController {
navigationController?.navigationBar.isTranslucent = true
rootViewController.dismiss(animated: true, completion: nil)
}
}
func cropViewController(_ cropViewController: CropViewController, didFinishCancelled cancelled: Bool) {
navigationController?.navigationBar.isTranslucent = true
dismiss(animated: true, completion: nil)
}
}
extension UIBarButtonItem {
static func menuButton(_ target: Any?,
action: Selector,
imageName: String,
size:CGSize = CGSize(width: 32, height: 32),
tintColor:UIColor?) -> UIBarButtonItem
{
let button = UIButton(type: .system)
button.tintColor = tintColor
button.setImage(UIImage(named: imageName), for: .normal)
button.addTarget(target, action: action, for: .touchUpInside)
let menuBarItem = UIBarButtonItem(customView: button)
menuBarItem.customView?.translatesAutoresizingMaskIntoConstraints = false
menuBarItem.customView?.heightAnchor.constraint(equalToConstant: size.height).isActive = true
menuBarItem.customView?.widthAnchor.constraint(equalToConstant: size.width).isActive = true
return menuBarItem
}
}
================================================
FILE: FSNotes iOS/Info.plist
================================================
CFBundleDevelopmentRegion
$(DEVELOPMENT_LANGUAGE)
CFBundleDisplayName
FSNotes
CFBundleDocumentTypes
CFBundleTypeExtensions
textbundle
CFBundleTypeIconFiles
TextBundle.icns
CFBundleTypeMIMETypes
text/x-textbundle
CFBundleTypeName
TextBundle
CFBundleTypeRole
Editor
LSHandlerRank
Alternate
LSItemContentTypes
org.textbundle.package
CFBundleTypeExtensions
md
markdown
mmd
multimarkdown
mdown
mkdn
mkd
mdwn
mdtxt
mdtext
mdml
CFBundleTypeMIMETypes
text/x-markdown
CFBundleTypeName
Markdown document
CFBundleTypeRole
Editor
LSHandlerRank
Alternate
LSItemContentTypes
net.daringfireball.markdown
CFBundleExecutable
$(EXECUTABLE_NAME)
CFBundleGetInfoString
CFBundleIdentifier
$(PRODUCT_BUNDLE_IDENTIFIER)
CFBundleInfoDictionaryVersion
6.0
CFBundleName
FSNotes
CFBundlePackageType
APPL
CFBundleShortVersionString
$(MARKETING_VERSION)
CFBundleURLTypes
CFBundleTypeRole
Viewer
CFBundleURLIconFile
makeNote
CFBundleURLName
co.fluder.mobile.FSNotes-iOS
CFBundleURLSchemes
fsnotes
CFBundleTypeRole
Viewer
CFBundleURLIconFile
makeNote
CFBundleURLName
co.fluder.mobile.FSNotes-iOS
CFBundleURLSchemes
nv
CFBundleTypeRole
Viewer
CFBundleURLIconFile
makeNote
CFBundleURLName
co.fluder.mobile.FSNotes-iOS
CFBundleURLSchemes
nvalt
CFBundleVersion
$(CURRENT_PROJECT_VERSION)
LSApplicationCategoryType
public.app-category.productivity
LSRequiresIPhoneOS
LSSupportsOpeningDocumentsInPlace
NSAppTransportSecurity
NSAllowsArbitraryLoads
NSCameraUsageDescription
Needs for attach photo in notes
NSFaceIDUsageDescription
Note encryption and decryption with FaceID
NSHumanReadableCopyright
NSLocationWhenInUseUsageDescription
Requested when photo attached
NSPhotoLibraryAddUsageDescription
Needs permission to write images in photos app
NSPhotoLibraryUsageDescription
Needs for attach images in notes
NSPrivacyAccessedAPITypes
NSPrivacyAccessedAPIType
NSPrivacyAccessedAPICategoryActiveKeyboards
NSPrivacyAccessedAPITypeReasons
54BD.1
NSPrivacyAccessedAPIType
NSPrivacyAccessedAPICategoryFileTimestamp
NSPrivacyAccessedAPITypeReasons
DDA9.1
NSPrivacyAccessedAPIType
NSPrivacyAccessedAPICategorySystemBootTime
NSPrivacyAccessedAPITypeReasons
35F9.1
NSPrivacyAccessedAPIType
NSPrivacyAccessedAPICategoryUserDefaults
NSPrivacyAccessedAPITypeReasons
CA92.1
NSUbiquitousContainers
iCloud.co.fluder.fsnotes
NSUbiquitousContainerIsDocumentScopePublic
NSUbiquitousContainerSupportedFolderLevels
One
NSUserActivityTypes
es.fsnot.handoff-open-note
UIAppFonts
SourceCodePro-Bold.ttf
SourceCodePro-Black.ttf
SourceCodePro-Regular.ttf
SourceCodePro-It.ttf
SourceCodePro-BoldIt.ttf
UIApplicationSceneManifest
UIApplicationSupportsMultipleScenes
UISceneConfigurations
UIWindowSceneSessionRoleApplication
UISceneConfigurationName
Default Configuration
UISceneDelegateClassName
$(PRODUCT_MODULE_NAME).SceneDelegate
UISceneStoryboardFile
Main
UIBackgroundModes
fetch
remote-notification
UIFileSharingEnabled
UILaunchStoryboardName
Launch Screen
UIMainStoryboardFile
Main
UISupportedInterfaceOrientations
UIInterfaceOrientationPortrait
UIInterfaceOrientationLandscapeLeft
UIInterfaceOrientationLandscapeRight
UISupportedInterfaceOrientations~ipad
UIInterfaceOrientationPortrait
UIInterfaceOrientationPortraitUpsideDown
UIInterfaceOrientationLandscapeLeft
UIInterfaceOrientationLandscapeRight
UISupportsDocumentBrowser
UIViewControllerBasedStatusBarAppearance
UTExportedTypeDeclarations
UTTypeConformsTo
com.apple.package
UTTypeDescription
TextBundle
UTTypeIconFiles
TextBundle.icns
UTTypeIdentifier
org.textbundle.package
UTTypeTagSpecification
public.filename-extension
textbundle
UTTypeConformsTo
public.data
UTTypeDescription
Markdown
UTTypeIconFiles
Markdown.icns
UTTypeIdentifier
net.daringfireball.markdown
UTTypeTagSpecification
public.filename-extension
md
markdown
================================================
FILE: FSNotes iOS/InfoPlist.xcstrings
================================================
{
"sourceLanguage" : "en",
"strings" : {
"CFBundleDisplayName" : {
"comment" : "Bundle display name",
"extractionState" : "extracted_with_value",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "FSNotes"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
}
}
},
"CFBundleGetInfoString" : {
"comment" : "Get Info string",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : ""
}
}
}
},
"CFBundleName" : {
"comment" : "Bundle name",
"extractionState" : "extracted_with_value",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "FSNotes"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
}
}
},
"Markdown" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Markdown"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "Markdown"
}
}
}
},
"NSCameraUsageDescription" : {
"comment" : "Privacy - Camera Usage Description",
"extractionState" : "extracted_with_value",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Potřeba pro přidávání fotek do poznámek"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sie müssen ein Foto zu Notizen hinzufügen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Needs for attach photo in notes"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Needs for attach photo in notes"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नोट्स में फोटो संलग्न करने की आवश्यकता"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "E' necessario per poter aggiungere foto nelle note"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "撮影した写真をノートに追加できるようにするため"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Behoeften voor het bijvoegen van foto in notities"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Necessário para anexar fotos às notas"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Потреби вкладати фото в нотатки"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "需要在笔记中附加照片"
}
}
}
},
"NSFaceIDUsageDescription" : {
"comment" : "Privacy - Face ID Usage Description",
"extractionState" : "extracted_with_value",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Šifrování a dešifrování poznámek pomocí Face ID"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ver- und Entschlüsselung mit FaceID"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Note encryption and decryption with FaceID"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Note encryption and decryption with FaceID"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "FaceID के साथ नोट्स एन्क्रिप्शन और डिक्रिप्शन"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Crittografia e decrittografia delle note con FaceID"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "FaceIDによるノートの暗号化・復号化のため"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Let op codering en decodering met FaceID"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Criptografar e descriptografar com FaceID"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Шифрування та дешифрування за допомогою FaceID"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "注意使用 Face 进行加密和解密"
}
}
}
},
"NSHumanReadableCopyright" : {
"comment" : "Copyright (human-readable)",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : ""
}
}
}
},
"NSLocationWhenInUseUsageDescription" : {
"comment" : "Privacy - Location When In Use Usage Description",
"extractionState" : "extracted_with_value",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vyžádáno při připojení fotky"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Wird beim Anhängen eines Fotos angefordert"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Requested when photo attached"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Requested when photo attached"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "फोटो संलग्न होने पर अनुरोध"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "E' richiesto quando viene allegata una foto"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "画像を挿入した際にリクエストされます"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Gevraagd wanneer foto bijgevoegd"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Necessário quando existem fotos anexadas"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Потрібен дозвіл коли додається фотографія у нотатку"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "附上照片时请求"
}
}
}
},
"NSPhotoLibraryAddUsageDescription" : {
"comment" : "Privacy - Photo Library Additions Usage Description",
"extractionState" : "extracted_with_value",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Potřeba pro ukládání fotek do knihovny"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Erfordert eine Berechtigung zum Aufzeichnen von Bildern in der Foto-App"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Needs permission to write images in photos app"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Needs permission to write images in photos app"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "फ़ोटो ऐप में चित्र लिखने के लिए अनुमति की आवश्यकता"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "E' necessario il permesso in scrittura per salvare immagini nell'app Foto"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "挿入した画像をライブラリに保存する際に必要です"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Heeft toestemming nodig om afbeeldingen in de foto-app te schrijven"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Precisa de permissão para escrever imagens no aplicativo de fotos"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Потрібен дозвіл на запис зображень у додаток для фотографій"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "需要权限才能在照片应用中写入图像"
}
}
}
},
"NSPhotoLibraryUsageDescription" : {
"comment" : "Privacy - Photo Library Usage Description",
"extractionState" : "extracted_with_value",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Potřeba pro připojení obrázků do poznámek"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Erfordert das Anhängen von Bildern an Notizen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Needs for attach images in notes"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Needs for attach images in notes"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नोट्स में चित्र संलग्न करने की आवश्यकता"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "E' necessario per allegare immagini nelle note"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "画像をノートに挿入する際に必要です"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Behoeften voor het toevoegen van afbeeldingen in notities"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Necessário para anexar imagens às notas"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Потрібен дозвіл коли додається зображення у нотатку"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "需要在笔记中附加图像"
}
}
}
},
"TextBundle" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "TextBundle"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "TextBundle"
}
}
}
}
},
"version" : "1.0"
}
================================================
FILE: FSNotes iOS/Launch Screen.storyboard
================================================
================================================
FILE: FSNotes iOS/LaunchImage.launchimage/Contents.json
================================================
{
"images": [
{
"extent": "full-screen",
"idiom": "iphone",
"subtype": "2436h",
"filename": "Default1125x2436.png",
"minimum-system-version": "11.0",
"orientation": "portrait",
"scale": "3x"
},
{
"extent": "full-screen",
"idiom": "iphone",
"subtype": "2436h",
"filename": "Default2436x1125.png",
"minimum-system-version": "11.0",
"orientation": "landscape",
"scale": "3x"
},
{
"orientation": "landscape",
"idiom": "tv",
"filename": "Default3840x2160.png",
"extent": "full-screen",
"minimum-system-version": "11.0",
"scale": "2x"
},
{
"orientation": "landscape",
"idiom": "tv",
"filename": "Default1920x1080.png",
"extent": "full-screen",
"minimum-system-version": "9.0",
"scale": "1x"
},
{
"extent": "full-screen",
"idiom": "iphone",
"subtype": "736h",
"filename": "Default1242x2208.png",
"minimum-system-version": "8.0",
"orientation": "portrait",
"scale": "3x"
},
{
"extent": "full-screen",
"idiom": "iphone",
"subtype": "736h",
"filename": "Default2208x1242.png",
"minimum-system-version": "8.0",
"orientation": "landscape",
"scale": "3x"
},
{
"extent": "full-screen",
"idiom": "iphone",
"subtype": "667h",
"filename": "Default750x1334.png",
"minimum-system-version": "8.0",
"orientation": "portrait",
"scale": "2x"
},
{
"orientation": "portrait",
"idiom": "iphone",
"filename": "Default640x960.png",
"extent": "full-screen",
"minimum-system-version": "7.0",
"scale": "2x"
},
{
"extent": "full-screen",
"idiom": "iphone",
"subtype": "retina4",
"filename": "Default640x1136.png",
"minimum-system-version": "7.0",
"orientation": "portrait",
"scale": "2x"
},
{
"orientation": "portrait",
"idiom": "ipad",
"filename": "Default768x1024.png",
"extent": "full-screen",
"minimum-system-version": "7.0",
"scale": "1x"
},
{
"orientation": "landscape",
"idiom": "ipad",
"filename": "Default1024x768.png",
"extent": "full-screen",
"minimum-system-version": "7.0",
"scale": "1x"
},
{
"orientation": "portrait",
"idiom": "ipad",
"filename": "Default1536x2048.png",
"extent": "full-screen",
"minimum-system-version": "7.0",
"scale": "2x"
},
{
"orientation": "landscape",
"idiom": "ipad",
"filename": "Default2048x1536.png",
"extent": "full-screen",
"minimum-system-version": "7.0",
"scale": "2x"
},
{
"orientation": "portrait",
"idiom": "iphone",
"filename": "Default320x480.png",
"extent": "full-screen",
"scale": "1x"
},
{
"orientation": "portrait",
"idiom": "iphone",
"filename": "Default640x960.png",
"extent": "full-screen",
"scale": "2x"
},
{
"orientation": "portrait",
"idiom": "iphone",
"filename": "Default640x1136.png",
"extent": "full-screen",
"subtype": "retina4",
"scale": "2x"
},
{
"orientation": "portrait",
"idiom": "ipad",
"filename": "Default768x1024.png",
"extent": "full-screen",
"scale": "1x"
},
{
"orientation": "landscape",
"idiom": "ipad",
"filename": "Default1024x768.png",
"extent": "full-screen",
"scale": "1x"
},
{
"orientation": "portrait",
"idiom": "ipad",
"filename": "Default1536x2048.png",
"extent": "full-screen",
"scale": "2x"
},
{
"orientation": "landscape",
"idiom": "ipad",
"filename": "Default2048x1536.png",
"extent": "full-screen",
"scale": "2x"
}
],
"info": {
"version": 1,
"author": "fanstudio"
}
}
================================================
FILE: FSNotes iOS/Localizable.xcstrings
================================================
{
"sourceLanguage" : "en",
"strings" : {
"..." : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "…"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "..."
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "..."
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "..."
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "..."
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "..."
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "..."
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "..."
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "..."
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "…"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "..."
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "..."
}
}
}
},
"+" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "+"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "+"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "+"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "+"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "+"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "+"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "+"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "+"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "+"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "+"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "+"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "+"
}
}
}
},
"✅ - " : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "✅ -"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "✅ - "
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "✅ - "
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "✅ - "
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "✅ - "
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "✅ - "
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "✅ - "
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "✅ - "
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "✅ - "
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "✅ -"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "✅ - "
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "✅ - "
}
}
}
},
"Add External Folder" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Přidat externí složku"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Externer Ordner"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dossier externe"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "बाह्य फ़ोल्डर जोड़ें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cartella esterna"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "外部フォルダを追加"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Externe map"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pasta Externa"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Добавить внешнюю папку"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Harici Klasör Ekle"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Зовнішня папка"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "添加外部文件夹"
}
}
}
},
"Advanced" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pokročilé"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Profi"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Avancé"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "उन्नत"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Esteso"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "プロ"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verlengd"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Estendido"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Расширенные"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Gelişmiş"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Розширені"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "高级"
}
}
}
},
"Are you sure you want to delete all versions of this note?" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Určitě chcete smazat všechny verze této poznámky?"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Möchten Sie wirklich alle Versionen dieser Notiz löschen?"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Voulez-vous vraiment supprimer toutes les versions de cette note ?"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "क्या आप वाकई इस नोट के सभी संस्करण हटाना चाहते हैं?"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sei sicuro di voler eliminare tutte le versioni di questa nota?"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "このノートの全バージョンを削除しますか?"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Weet u zeker dat u alle versies van deze notitie wilt verwijderen?"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tem certeza de que deseja excluir todas as versões desta nota?"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вы уверены, что хотите удалить все версии этой заметки?"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bu notun tüm sürümlerini silmek istediğinizden emin misiniz?"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ви впевнені, що хочете видалити всі версії цієї нотатки?"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "是否确定要删除此笔记的所有历史版本?"
}
}
}
},
"Are you sure you want to delete the history of all notes?" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Určitě chcete smazat historii všech poznámek?"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Möchten Sie den Verlauf aller Notizen wirklich löschen?"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Voulez-vous vraiment supprimer l'historique de toutes les notes ?"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "क्या आप वाकई सभी नोट्स का इतिहास हटाना चाहते हैं?"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sei sicuro di voler eliminare la cronologia di tutte le note?"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "すべてのノートの履歴を削除しますか?"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Weet u zeker dat u de geschiedenis van alle notities wilt verwijderen?"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tem certeza de que deseja excluir o histórico de todas as notas?"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вы уверены, что хотите удалить историю всех заметок?"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tüm notların geçmişini silmek istediğinizden emin misiniz?"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ви впевнені, що хочете видалити історію всіх нотаток?"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "是否确定要删除所有笔记的历史版本?"
}
}
}
},
"Are you sure you want to delete this image?" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Určitě chcete smazat tento obrázek?"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Möchten Sie dieses Bild wirklich löschen?"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Êtes-vous sûr de vouloir supprimer cette image ?"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "क्या आप वाकई में इस छवि को हटाना चाहते हैं?"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sei sicuro di voler eliminare questa immagine?"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "この画像を削除しますか?"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Weet je zeker dat je deze afbeelding wilt verwijderen?"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tem certeza de que deseja apagar esta imagem?"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вы уверены, что хотите удалить это изображение?"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bu resmi silmek istediğinizden emin misiniz?"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ви впевнені, що хочете видалити це зображення?"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "是否确定要删除此图像?"
}
}
}
},
"Ascending" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vzestupně"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aufsteigend"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ascendant"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "आरोही"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Crescente"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "昇順"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Oplopend"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ascendente"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Восходящее"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Artan"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Висхідний"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "升序"
}
}
}
},
"Auto Rename By Title" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Podle nadpisu"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nach Titel umbenennen"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renommer automatiquement par titre"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "शीर्षक द्वारा स्वतः नाम बदलें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rinomina per titolo"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "タイトルをファイル名に自動反映"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Naam wijzigen op titel"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renomeação automática por título"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Авто переименование "
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Başlığa Göre Otomatik Yeniden Adlandır"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Автоматичне перейменування"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "按内容第一行自动重命名"
}
}
}
},
"Autocorrection" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Automatická oprava"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Autokorrektur"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Autocorrection"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "स्वतः सुधार"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Autocorrezione"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "自動訂正"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Autocorrectie"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Auto correção"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Автокоррекция"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Otomatik Düzeltme"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Автокорекція"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "自动校正"
}
}
}
},
"Autoname By Title" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Automatické pojmenování podle názvu"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Automatische Benennung nach Titel"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dénomination automatique par titre"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "शीर्षक के अनुसार स्वचालित नामकरण"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Denominazione automatica per titolo"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "タイトルによる自動命名"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Automatische naamgeving op titel"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nomeação automática por título"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Автоименование по заголовку"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Başlığa Göre Otomatik Adlandırma"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Автоіменування за заголовком"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "按标题自动命名"
}
}
}
},
"build" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "build"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "version"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "build"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "निर्माण"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "build"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ビルド"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "build"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "versão"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "сборка"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "oluştur"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "білд"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "构建"
}
}
}
},
"Cancel" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zrušit"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Abbrechen"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Annuler"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "रद्द करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Annulla"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "キャンセル"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Annuleer"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cancelar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Отменить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "İptal"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Скасувати"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "取消"
}
}
}
},
"Change Creation Date" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Změnit datum vytvoření"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Datum erstellt"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Modifier la Date de création"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "निर्माण तिथि बदलें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Data di creazione"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "作成日"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Datum gecreeërd"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Data Criada"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Изменить дату создания"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Oluşturma Tarihini Değiştir"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Дата створення"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "更改创建日期"
}
}
}
},
"Check Spelling" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kontrolovat pravopis"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rechtschreibung prüfen"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vérifier l’orthographique"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "स्पेलिंग जांचे"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Controllo ortografico"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "スペルチェック"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Spellingcheck"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verificação Ortográfica"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Проверять орфографию"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yazımı Denetle"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перевірка правопису"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "检查拼写"
}
}
}
},
"Code" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kód"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Code"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Code"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कोड"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Codice"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "コード"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Code"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Código"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Код"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kod"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Код"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "代码字体"
}
}
}
},
"Code Block Live Highlighting" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Živé zvýraznění kódu "
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Code hervorheben"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mise en surbrillance automatique des blocs de code"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कोड ब्लॉक लाइव हाइलाइटिंग"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Evidenzia il blocco di codice attivo"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "コードブロックの色付け"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Codeblok live markering"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Realçar bloco de código"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Живая подсветка кода"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kod Bloğu Canlı Vurgulama"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Живе підсвічування блоку коду"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "代码块实时高亮"
}
}
}
},
"Code Theme" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Motiv kódu"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Code-Design"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Thème de codes"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कोड थीम"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tema del codice"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "コードテーマ"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Code thema"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tema do código"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Код темы"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kod Teması"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Тема коду"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "代码主题"
}
}
}
},
"Compatible with Bear and Ulysses (textbundle), markdown, txt." : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kompatibilní s Bear a Ulysses (textbundle), markdown, txt."
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kompatibel mit Bear und Ulysses (Textbundle), markdown, txt."
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Compatible avec Bear et Ulysses (textbundle), markdown, txt."
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bear और Ulysses (textbundle), markdown, txt के साथ संगत।"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Compatibile con Bear and Ulysses (textbundle), markdown, txt."
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bear and Ulysses (textbundle), markdown, txtと互換性があります"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Compatibel met Bear en Ulysses (textbundle), markdown, txt."
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Compatível com Bear e Ulysses (textbundle), markdown, txt."
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Совместим с Bear и Ulysses (textbundle), markdown, txt."
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bear ve Ulysses (textbundle), markdown, txt ile uyumludur."
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сумісний з Bear and Ulysses (textbundle), markdown, txt."
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "兼容 Bear(熊掌记) and Ulysses (textbundle),markdown,txt."
}
}
}
},
"Container" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kontejner"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Container"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Container"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कंटेनर"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Container"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "コンテナ"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Container"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Container"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Контейнер"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kapsayıcı"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Контейнер"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "容器"
}
}
}
},
"Copy Plain Text" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kopírovat prostý text"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Text kopieren"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copier le texte brut"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "सादा पाठ कॉपी करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copia testo semplice"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "プレインテキストとしてコピー"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kopieer platte tekst"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copiar texto simples"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Скопировать обычный текст"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Düz Metni Kopyala"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Скопіювати звичайний текст"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "拷贝纯文本"
}
}
}
},
"Create Folder" : {
"comment" : "Main view popover table",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vytvořit složku"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordner erstellen"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Créer le dossier"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "फोल्डर बनाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Crea cartella"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "新規フォルダ"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Map aanmaken"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Criar pasta"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Создать папку"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Klasör Oluştur"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Створити папку"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "创建文件夹"
}
}
}
},
"Create folder:" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vytvořit složku:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordner erstellen:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Créer le dossier :"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "फोल्डर बनाएं:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Crea cartella:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "新規フォルダ:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Map aanmaken:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Criar pasta:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Создать папку:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Klasör oluştur:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Створити папку:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "创建文件夹:"
}
}
}
},
"Create Web Page" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vytvořit webovou stránku"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web-Seite erstellen"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Créer une page Web"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "वेब पेज बनाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Crea pagina web"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ウェブページの作成"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Create Web Page"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Criar página da Web"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Создать веб-страницу"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web Sayfası Oluştur"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Створити веб-сторінку"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "创建网页"
}
}
}
},
"Creation Date" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Datum vytvoření"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Erstelldatum"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Date de création"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "निर्माण तिथि"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Data di creazione"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "作成日"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aanmaakdatum"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Data de criação"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Дата создания"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Oluşturma Tarihi"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Датою створення"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "创建日期"
}
}
}
},
"Decrypt" : {
"comment" : "Main view popover table",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dešifrovat"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Entschlüsseln"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Déchiffrer"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "डिक्रिप्ट"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Decriptare"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Decrypt"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Decrypt"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Desencriptar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Расшифровать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Şifresini Çöz"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Розшифрувати"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "解密"
}
}
}
},
"Default Keyboard" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Výchozí klávesnice"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Standard-Tastatur"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clavier par défaut"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "डिफ़ॉल्ट कीबोर्ड"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tastiera predefinita"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "エディタで使用するデフォルトキーボード"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Standaard toetsenbord"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Teclado padrão"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Клавиатура по умолчанию"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Varsayılan Klavye"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Клавіатура за замовчуванням"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "默认键盘"
}
}
}
},
"Delete" : {
"comment" : "Table row action",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Smazat"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Löschen"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Supprimer"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "हटाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Elimina"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "削除"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verwijderen"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Eliminar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Удалить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sil"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Видалити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "删除"
}
}
}
},
"Delete Web Page" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Smazat webovou stránku"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web-Seite löschen"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Supprimer la page Web"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "वेब पेज हटाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Elimina pagina web"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ウェブページを削除する"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Webpagina verwijderen"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Excluir página da Web"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Удалить веб-страницу"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web Sayfasını Sil"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Видалити веб-сторінку"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "删除网页"
}
}
}
},
"Descending" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sestupně"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Absteigend"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Descendant"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "अवरोही"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Decrescente"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "降順"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aflopend"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Descendente"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Нисходящее"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Azalan"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Низхідний"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "降序"
}
}
}
},
"Documents" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dokumenty"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dokumente"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Documents"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "दस्तावेज़"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Documenti"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ドキュメント"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Documenten"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Documentos"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Документы"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Belgeler"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Документи"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "文件"
}
}
}
},
"Done" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hotovo"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Erledigt"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fait"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "हो गया"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fatto"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Done"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Gedaan"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Feito"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Готово"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tamamlandı"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Готово"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "完成"
}
}
}
},
"Duplicate" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Duplikovat"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Duplikat"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dupliquer"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "डुप्लिकेट"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Duplicare"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "複製"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Duplicaat"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Duplicada"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Дублировать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Çoğalt"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Створити копію"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "生成副本"
}
}
}
},
"Dynamic Type" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dynamické písmo"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dynamische Schriftart"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Type dynamique"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "गतिशील प्रकार"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tipizzazione dinamica"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ダイナミックタイプ"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dynamisch Type"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tipo dinâmico"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Динамический шрифт"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dinamik Tür"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Динамічний шрифт"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "动态类型"
}
}
}
},
"Editor" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Editor"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Editorin"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Éditeur"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "संपादक"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Editrice"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "エディタ"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Editor"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Editor"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Редактор"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Düzenleyici"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Редактор"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "编辑"
}
}
}
},
"Empty Bin" : {
"comment" : "Main view popover table",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vyprázdnit koš"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Leerer Behälter"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vider la Corbeille"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कूडा खाली करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cestino vuoto"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ゴミ箱を空にする"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lege bak"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Caixa vazia"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Очистить корзину"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Çöp Kutusunu Boşalt"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Очистити кошик"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "清空回收站"
}
}
}
},
"Encrypt" : {
"comment" : "Main view popover table",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zašifrovat"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verschlüsseln Sie"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Chiffrer"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "एन्क्रिप्ट"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Crittografare"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "エンクリプト"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Versleutel"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Encriptar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Зашифровать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Şifrele"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Зашифрувати"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "加密"
}
}
}
},
"Enter folder name" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zadejte název složky"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordnername eingeben"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Entrez le nom du dossier"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "फ़ोल्डर का नाम दर्ज करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Inserisci il nome della cartella"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "フォルダ名を入力"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ga naar onze mape"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Digite o nome da pasta"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Введите имя папки"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Klasör adını girin"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Введіть назву папки"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "输入文件夹名称"
}
}
}
},
"Enter Master Password" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zadejte hlavní heslo"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Passwort eingeben"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Entrez le mot de passe principal"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "मास्टर पासवर्ड दर्ज करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Inserisci la Master Password"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "マスターパスワードを入力"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Voer het hoofdwachtwoord in"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Introduzir Palavra-passe Mestra"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Введите мастер-пароль"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ana Parolayı Girin"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Введіть пароль"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "输入主密码"
}
}
}
},
"Enter new tag name" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zadejte název nové značky"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tag eingeben"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Entrez un nouveau nom d’étiquette"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नया टैग नाम दर्ज करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Interisci il nuovo nome del tag"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "新規タグ名を入力"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Voer een nieuwe tagnaam in"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Insira o novo nome da tag"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Введите новое имя тега"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yeni etiket adını girin"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Введіть назву тега"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "输入新标签名称"
}
}
}
},
"Enter note name" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zadejte název poznámky"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notizname eingeben"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Entrez le nom de la note"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नोट का नाम दर्ज करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Inserisci il nome della nota"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ノート名を入力"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Voer notitie naam in"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Introduzir nome da nota"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Введите название заметки"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Not adını girin"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Введіть назву нотатки"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "输入备注名称"
}
}
}
},
"Extension" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Přípona"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dateiformat"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Extension"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "एक्सटेंशन"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Estensione"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "拡張子"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Uitbreiding"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Extensão"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Расширение"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Uzantı"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Розширення"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "文件后缀格式"
}
}
}
},
"Family" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rodina"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Schriftfamilie"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Famille"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "परिवार"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Famiglia di font"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ファミリー"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lettertype familie"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Família de fontes"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Семья"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aile"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сімейство шрифтів"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "字体集"
}
}
}
},
"File with this name already exist" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Soubor s tímto názvem už existuje"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Eine Datei mit diesem Namen existiert bereits"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Un fichier avec ce nom existe déjà"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "इस नाम वाली फ़ाइल पहले से मौजूद है"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Il file con questo nome già esiste"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "同名のファイルがすでに存在しています"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bestand met deze naam bestaat al"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Já existe um ficheiro com este nome"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Файл с таким именем уже существует"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bu isimde dosya zaten mevcut"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Файл з цим іменем вже існує"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "具有此名称的文件已存在"
}
}
}
},
"Files" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Soubory"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Datei Format"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fichiers"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "फ़ाइल"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formato del file"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ファイル形式"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bestandsformaat"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formato de arquivo"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Файлы"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dosyalar"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Файли"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "文件"
}
}
}
},
"Files Naming" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Názvy souborů"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dateinamen"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nommage des fichiers"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "फ़ाइलों का नामकरण"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Denominazione dei file"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ファイル命名"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Naamgeving van bestanden"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nomenclatura de arquivos"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Именование файлов"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dosya Adlandırma"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Іменування файлів"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "文件命名"
}
}
}
},
"Folder name:" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Název složky:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordnername:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nom de dossier :"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "फ़ोल्डर का नाम:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nome cartella:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "フォルダ名:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Naam van de map:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nome da pasta:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Название папки:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Klasör adı:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Назва папки:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "文件夹名称:"
}
}
}
},
"Folder with this name already exist" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Složka s tímto názvem už existuje"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ein Ordner mit diesem Namen existiert bereits"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Un dossier avec ce nom existe déjà"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "इस नाम वाला फ़ोल्डर पहले से मौजूद है"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "La cartella con questo nome già esiste"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "同名のフォルダがすでに存在しています"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Map met deze naam bestaat al"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Já existe uma pasta com este nome"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Папка с таким именем уже существует"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bu isimde klasör zaten mevcut"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Папка з цим іменем вже існує"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "具有此名称的文件夹已存在"
}
}
}
},
"Folders" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Složky"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordner"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dossiers"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "फ़ोल्डर"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cartelle"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "プロジェクト"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mappen"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pastas"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Папки"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Klasörler"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Папки"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "文件夹"
}
}
}
},
"Font" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Písmo"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Schrift"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Police"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "फ़ॉन्ट"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Carattere"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "フォント"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lettertype"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Letra"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Шрифт"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yazı Tipi"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Шрифт"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "字体"
}
}
}
},
"Font Family" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rodina písma"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Schriftart"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Famille de police"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "फ़ॉन्ट परिवार"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tipo carattere"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "フォントファミリー"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lettertypefamilie"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Família do tipo de letra"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Семейство шрифтов"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yazı Tipi Ailesi"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сімейство шрифтів"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "字体集"
}
}
}
},
"Font Size" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Velikost písma"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Schriftgröße"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Taille de police"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "फ़ॉन्ट आकार"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dimensione carattere"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "フォントサイズ"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lettertypegrootte"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tamanho da letra"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Размер шрифта"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yazı Tipi Boyutu"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Розмір шрифту"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "字体大小"
}
}
}
},
"Format: Untitled Note" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formát: Poznámka bez názvu"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Format: Untitled Note"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Format : Note sans titre"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "प्रारूप: शीर्षक रहित नोट"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formato: Untitled Note"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "フォーマット: 無題のノート"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formaat: Untitled Note"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formato: Untitled Note"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Формат: Без названия"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Biçim: Başlıksız Not"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Формат: Untitled Note"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "格式:无标题笔记"
}
}
}
},
"Format: yyyy-MM-dd hh.mm.ss a" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formát: yyyy-MM-dd hh.mm.ss a"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Format: yyyy-MM-dd hh.mm.ss a"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Format : yyyy-MM-dd hh.mm.ss a"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "प्रारूप: yyyy-MM-dd hh.mm.ss a"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formato: yyyy-MM-dd hh.mm.ss a"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "フォーマット: yyyy-MM-dd hh.mm.ss a"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formaat: yyyy-MM-dd hh.mm.ss a"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formato: yyyy-MM-dd hh.mm.ss a"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Формат: yyyy-MM-dd hh.mm.ss a"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Biçim: yyyy-AA-gg hh.dd.ss a"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Формат: yyyy-MM-dd hh.mm.ss a"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "格式: yyyy-MM-dd hh.mm.ss a"
}
}
}
},
"Format: yyyyMMddHHmmss" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formát: yyyyMMddHHmmss"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Format: yyyyMMddHHmmss"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Format : yyyyMMddHHmmss"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "प्रारूप: yyyyMMddHHmmss"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formato: yyyyMMddHHmmss"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "フォーマット: yyyyMMddHHmmss"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formaat: yyyyMMddHHmmss"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formato: yyyyMMddHHmmss"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Формат: yyyyMMddHHmmss"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Biçim: yyyyAAggSSddss"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Формат: yyyyMMddHHmmss"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "格式: yyyyMMddHHmmss"
}
}
}
},
"FSNotes" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotları"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "FSNotes"
}
}
}
},
"General" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Obecné"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Allgemein"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Général"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "सामान्य"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Generali"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "一般"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Algemeen"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Geral"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Главные"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Genel"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Загальні"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "常规"
}
}
}
},
"Git" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "गिट"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git"
}
}
}
},
"Git Add/commit/push" : {
"comment" : "Main view popover table",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git přidat/commit/push"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git Add/commit/push"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git Add/commit/push"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "गिट जोड़ें/कमिट/पुश"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git Add/commit/push"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git Add/commit/push"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git Add/commit/push"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git Add/commit/push"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git Add/commit/push"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git Ekle/Gönder/Gönder"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git Add/commit/push"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git 添加/提交/推送"
}
}
}
},
"Git Settings" : {
"comment" : "Main view popover table",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nastavení Gitu"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git settings"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Paramètres git"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "गिट प्राथमिकताएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git settings"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git settings"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git settings"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git settings"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Настройки Git"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git Ayarları"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Налаштування Git"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "Git 设置"
}
}
}
},
"History" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Historie"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Geschichte"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Histoire"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "इतिहास"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Storia"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "履歴"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Geschiedenis"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "História"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "История"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Geçmiş"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Історія"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "笔记历史版本"
}
}
}
},
"iCloud Drive" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud ड्राइव"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Sürücüsü"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud Drive"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "iCloud 云同步"
}
}
}
},
"Icon" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ikona"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Icon"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Icône"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "आइकन"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Icon"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "アイコン"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Icoon"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ícone"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Иконка"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Simge"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Іконка програми"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "图标"
}
}
}
},
"Images source:" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zdroj obrázků:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bildquelle:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Source des images :"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "चित्र स्रोत:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fonti delle immagini:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "画像ソース:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Afbeeldingen bron:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fonte das imagens:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Источник изображений:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Görüntü kaynağı:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Джерело зображень:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "图片来源:"
}
}
}
},
"Import Notes" : {
"comment" : "Main view popover table\nSettings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Importovat poznámky"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Importieren"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Importer des notes"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नोट्स आयात करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Importa note"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ノートのインポート"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Importeren notities"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Importar notas"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Импортировать заметки"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notları İçe Aktar"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Імпортувати"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "导入笔记"
}
}
}
},
"Inbox" : {
"comment" : "Inbox in sidebar",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Příchozí"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Eingang"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Boîte de réception"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "इनबॉक्स"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "In Entrata"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "未整理"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Postvak In"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Caixa de entrada"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Входящие"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Gelen Kutusu"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вхідні"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "收集箱"
}
}
}
},
"Insert" : {
},
"Invalid Password" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Neplatné heslo"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ungültiges Passwort"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mot de passe incorrect"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "अवैध पासवर्ड"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Password non valida"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "無効なパスワードです"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ongeldig wachtwoord"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Palavra-passe inválida"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Неверный пароль"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Geçersiz Parola"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Недійсний пароль"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "密码无效"
}
}
}
},
"Library" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Knihovna"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Seitenleiste"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Barre latérale"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "लाइब्रेरी"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Barra laterale"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "サイドバー"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zijbalk"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Barra lateral"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Библиотека"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kütüphane"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Бічна панель"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "文库"
}
}
}
},
"Line Spacing" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Řádkování"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zeilenabstand"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Interligne"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पंक्ति रिक्ति"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Interlinea"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "行間隔"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Regelafstand"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Espaçamento entre linhas"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Расстояние между строками"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Satır Aralığı"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Міжрядковий інтервал"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "行距"
}
}
}
},
"Live Images Preview" : {
"comment" : "Settings",
"extractionState" : "stale",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Živý náhled obrázků"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bilder аnzeigen"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aperçu des images"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "लाइव छवियाँ पूर्वावलोकन"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Antemprima delle immagini"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ライブ画像プレビュー"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Toon afbeeldingen in de editor"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pré-visualização de imagens"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Предпросмотр изображений"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Canlı Görüntüler Önizlemesi"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Живий перегляд зображень"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "实况图像预览"
}
}
}
},
"Loading..." : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Načítání..."
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Laden..."
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Chargement..."
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "लोड हो रहा है..."
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Caricamento..."
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "読み込み中..."
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aan het laden..."
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Carregando..."
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Загрузка..."
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yükleniyor..."
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Завантаження..."
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "正在加载..."
}
}
}
},
"Lock" : {
"comment" : "Main view popover table",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zamknout"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sperren"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verrouiller"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "लॉक"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Blocca"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ロック"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vergrendel"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Trancar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заблокировать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kilit"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заблокувати"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "上锁"
}
}
}
},
"Master" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hlavní"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Master"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Maître"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "मास्टर"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Master"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "マスター"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Master"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Master"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Мастер"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ana"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Головний"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "管理员"
}
}
}
},
"Master password:" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hlavní heslo:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Master Passwort:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mot de passe maître :"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "मास्टर पासवर्ड:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Password principale:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "マスターパスワード:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Master wachtwoord:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Senha mestra:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Мастер-пароль:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ana parola:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Головний пароль:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "主密码:"
}
}
}
},
"MathJax" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "MathJax"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "MathJax"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "MathJax"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "MathJax"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "MathJax"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "MathJax"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "MathJax"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "MathJax"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "MathJax"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "MathJax"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "MathJax"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "MathJax 数学公式"
}
}
}
},
"Modification Date" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Datum změny"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Änderungsdatum"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Date de modification"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "सुधार की तारीख"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Data di modifica"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "変更日"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Wijzigingsdatum"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Data de modificação"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Дата модификации"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Değişiklik Tarihi"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Датою модифікації"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "修改日期"
}
}
}
},
"More" : {
"comment" : "Table row action",
"extractionState" : "stale",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Více"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mehr"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Plus"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "अधिक"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Altro"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "他"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nog steeds"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Todavía"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ещё"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Daha Fazla"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ще"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "更多"
}
}
}
},
"Move" : {
"comment" : "Move view",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Přesunout"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bewegen"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Déplacer"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "स्थानांतरण"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sposta"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "移動"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verplaats"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mover"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Переместить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Taşı"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перемістити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "移动"
}
}
}
},
"New Note" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nová poznámka"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Neues Dokument"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nouvelle Note"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नया नोट"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nuovo documento"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "新規ドキュメント"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nieuw document"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Novo Documento"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Новая заметка"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yeni Not"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Нова нотатка"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "新建笔记"
}
}
}
},
"None" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Žádné"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Standard"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aucun"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कोई भी नहीं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Predefinita"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "なし"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Standaard"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Por padrão"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Нет"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hiçbiri"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "За замовчуванням"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "无"
}
}
}
},
"Notes" : {
"comment" : "Notes in sidebar\nSidebar items\nSidebar label",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Poznámky"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notizen"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notes"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नोट"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Note"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "すべて"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notities"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notas"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заметки"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notlar"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Нотатки"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "所有笔记"
}
}
}
},
"Notes List" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Seznam poznámek"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notizenliste"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Liste de notes"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नोट्स सूची"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lista note"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ノートリスト"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notitielijst"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lista de notas"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Список заметок"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notlar Listesi"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Лист нотаток"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "笔记列表"
}
}
}
},
"Open in Files.app" : {
"comment" : "Main view popover table",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Otevřit v aplikaci Soubory"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "In Files.app öffnen"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ouvrir dans Files.app"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "Files.app में खोलें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Apri in Files.app"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ファイルで開く"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Openen in Files.app"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Abra em Files.app"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Открыть в Files.app"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Files.app'te aç"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Відкрийте в Files.app"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "在文件应用打开所在位置"
}
}
}
},
"Open Note" : {
"comment" : "Document opened",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Otevřít poznámku"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Geöffnete Notiz"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ouvrir la note"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नोट खोलें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Apri nota"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ノートを開く"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Open notitie"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Abrir nota"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Открыть заметку"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notu aç"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Відкрита нотатка"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "打卡笔记"
}
}
}
},
"Passphrase" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Přístupová fráze"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Passphrase"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Passphrase"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पासफ्रेज"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Passphrase"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Passphrase"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Passphrase"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Passphrase"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Пассфраза"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Parola"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Парольна фраза"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "密码锁"
}
}
}
},
"Password" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Heslo"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Passwort"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mot de passe"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पासवर्ड"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Password"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "パスワード"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Wachtwoord"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Palavra-passe"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Пароль"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Parola"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Пароль"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "密码"
}
}
}
},
"Password has been successfully changed" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Heslo úspěšně změněno"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Das Passwort wurde erfolgreich geändert"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Le mot de passe a été modifié avec succès"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पासवर्ड सफलतापूर्वक बदल दिया गया है"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "La password è stata modificata con successo"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "パスワードの変更に成功しました"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Wachtwoord is succesvol gewijzigd"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "A palavra-passe foi alterada com êxito"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Пароль был успешно изменен"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Parola başarıyla değiştirildi"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Пароль успішно змінено"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "密码已被成功修改"
}
}
}
},
"Password:" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Heslo:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Passwort:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mot de passe :"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पासवर्ड:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Password:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "パスワード"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Wachtwoord:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Palavra-passe:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Пароль:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Parola:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Пароль:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "密码:"
}
}
}
},
"Photos" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fotky"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fotos"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Photos"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "Photos"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Foto"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "画像"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Foto's"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fotos"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Фото"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fotoğraflar"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Фотографії"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "照片"
}
}
}
},
"Picture removing" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Odebírání fotek"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bild entfernen"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Suppression de l'image"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "चित्र हटाया जा रहा है"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rimozione dell'immagine"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "削除する画像"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Foto verwijderen"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remoção de imagem"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Удаление изображения"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Resim kaldırılıyor"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Видалення зображення"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "图片删除"
}
}
}
},
"Pin" : {
"comment" : "Table row action",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Připnout"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fixieren"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Épingler"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पिन"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fissa"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "メモをピンで固定"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pin"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Fixar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Закрепить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pin"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Закріпити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "笔记置顶"
}
}
}
},
"Please enter valid password" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Prosím zadejte platné heslo"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bitte geben Sie ein gültiges Passwort ein"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Merci de saisir un mot de passe correct"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कृपया वैध पासवर्ड दर्ज करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Per favore inserisci una password valida"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "有効なパスワードを入力してください"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Voer a.u.b. geldig wachtwoord in"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Por favor insira uma palavra-passe válida"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Пожалуйста, введите правильный пароль"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lütfen geçerli parolayı girin"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Введіть дійсний пароль"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "请输入有效密码"
}
}
}
},
"Please try again" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zkuste to znovu"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bitte versuchen Sie es erneut"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Veuillez réessayer"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कृपया पुन: प्रयास करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Si prega di riprovare"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "再度お試しください"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Probeer het opnieuw"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tente novamente"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Пожалуйста, попробуйте еще раз"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lütfen tekrar deneyin"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Будь ласка, спробуйте ще разn"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "请再试一试"
}
}
}
},
"Private Key" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Soukromý klíč"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Private key"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clé privée"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "निजी चाबी"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Private key"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Private key"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Private key"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Private key"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Приватный ключ"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Özel Anahtar"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Приватний ключ"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "私密密钥"
}
}
}
},
"Project removing ❌" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Odebírání projektu ❌"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Projekt entfernen ❌"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Suppression de projet ❌"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "प्रोजेक्ट हटाया जा रहा है ❌"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rimozione progetto ❌"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "削除するプロジェクト ❌"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Project verwijderen ❌"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remover projeto❌"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Устранение проекта ❌"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Proje kaldırılıyor ❌"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Видалення проекту ❌"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "项目删除 ❌"
}
}
}
},
"Public Key (optional)" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Veřejný klíč (nepovinné)"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Public key (optional)"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Clé public (facultatif)"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "सार्वजनिक कुंजी (वैकल्पिक)"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Public key (opzionale)"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Public key (任意)"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Public key (optionele)"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Public key (facultativo)"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Открытый ключ (необязательно)"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Genel Anahtar (isteğe bağlı)"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Відкритий ключ (необов'язково)"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "公共密钥 (可选)"
}
}
}
},
"Pull (every 30 sec)" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pull (každých 30 sekund)"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pull (alle 30 Sekunden)"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pull (toutes les 30 secondes)"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "खींचें (प्रत्येक 30 सेकंड)"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pull (ogni 30 secondi)"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pull (30秒ごと)"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pull (elke 30 sec)"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pull (a cada 30 segundos)"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pull (каждые 30 секунд)"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Çek (her 30 saniyede bir)"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Тягнути (кожні 30 сек)"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pull (每隔 30 秒)"
}
}
}
},
"Remove Encryption" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Odebrat šifrování"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verschlüsselung entfernen"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Supprimer le chiffrage"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "एन्क्रिप्शन हटाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rimuovi la crittografia"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ロックを削除"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verwijder versleuteling"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remover criptografia"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Удалить шифрование"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Şifrelemeyi kaldır"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Зняти шифрування"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "移除加密"
}
}
}
},
"Remove Folder" : {
"comment" : "Main view popover table",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Odebrat složku"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordner enfernen"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Supprimer le dossier"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "फ़ोल्डर हटाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rimuovi cartella"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "フォルダの削除"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verwijder map"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remover pasta"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Удалить папку"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Klasörü kaldır"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Видалити папку"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "移除文件夹"
}
}
}
},
"Remove Tag" : {
"comment" : "Main view popover table",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Odebrat značku"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tag entfernen"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Enlever l’étiquette"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "टैग हटाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rimuovi tag"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "削除されたタグ"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tag verwijderen"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remover tag"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Удалить тег"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Etiketi kaldır"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Видалити тег"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "移除标签"
}
}
}
},
"Rename" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Přejmenovat"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Umbenennen"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renommer"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नाम बदलें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rinomina"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "名称変更"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hernoemen"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renomear"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Переименовать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yeniden adlandır"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перейменувати"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "重命名"
}
}
}
},
"Rename Folder" : {
"comment" : "Main view popover table",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Přejmenovat složku"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordner umbenennen"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renommer le dossier"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "फ़ोल्डर का नाम बदलें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rinomina cartella"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "フォルダの名称変更"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Naam map wijzigen"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renomear pasta"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Переименовать папку"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Klasörü yeniden adlandır"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перейменувати папку"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "重命名文件夹"
}
}
}
},
"Rename folder:" : {
"comment" : "Popover table",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Přejmenovat složku:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordner löschen:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renommer le dossier :"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "फ़ोल्डर का नाम बदलें:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rinomina cartella:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "フォルダの名称変更:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Naam map wijzigen:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renomear pasta:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Переименовать папку:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Klasörü yeniden adlandır:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Переименовать папку:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "重命名文件夹:"
}
}
}
},
"Rename note:" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Přejmenovat poznámku:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notiz umbenennen:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renommer la note"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नोट का नाम बदलें:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rinomina nota:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ノートの名称変更:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hernoem notitie:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renomear nota:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Переименовать заметку:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notu yeniden adlandır:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перейменувати нотатку:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "重命名笔记:"
}
}
}
},
"Rename Tag" : {
"comment" : "Main view popover table",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Přejmenovat značku"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tag umbenennen"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renommer l’étiquette"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "टैग का नाम बदलें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rinomina tag"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "タグの名称変更"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hernoem tag"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renomear tag"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Переименовать тег"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Etiketi yeniden adlandır"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перейменувати тег"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "重命名标签"
}
}
}
},
"Rename tag:" : {
"comment" : "Popover table",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Přejmenovat značku:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tag umbenennen:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renommer l’étiquette :"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "टैग का नाम बदलें:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rinomina tag:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "タグの名称変更:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hernoem tag:"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Renomear tag:"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Переименовать тег:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Etiketi yeniden adlandır:"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Переименовать тег:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "重命名标签:"
}
}
}
},
"Save" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Uložit"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Speichern Sie"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Enregistrer"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "सहेजें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Risparmiare"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "セーブ"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Save"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Guardar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сохранить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kaydet"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Зберегти"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "保存"
}
}
}
},
"Save Clipboard" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Uložit schránku"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kopieren"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Enregistrer le presse-papiers"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "क्लिपबोर्ड सहेजें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Salva gli appunti"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "クリップボードの内容を保存"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bewaar klembord"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Salvar área de transferência"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сохранить буфер обмена"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Panoya kaydet"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Зберегти буфер обміну"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "保存剪贴板"
}
}
}
},
"Save Revision" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Uložit úpravy"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Revision speichern"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sauvegarder la révision"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "संशोधन सहेजें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Salva revisione"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "バージョンを保存"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bewaar revisie"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Guardar revisão"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сохранить версию"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Revizyonu kaydet"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Зберегти ревізію"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "保存修订版"
}
}
}
},
"Saved versions" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Uložené verze"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Gespeicherte Versionen"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Versions enregistrées"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "सहेजे गए संस्करण"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Versioni salvate"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "保存されたバージョン"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Opgeslagen versies"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Versões salvas"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сохраненные версии"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kaydedilen sürümler"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Збережені версії"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "保存的历史版本"
}
}
}
},
"Search or create" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hledat / vytvořit"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Suchen oder erstellen"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rechercher ou créer"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "खोजें या बनाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cerca o crea"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "検索または新規作成"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zoek en creëer"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pesquisar e criar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Найти или создать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ara veya oluştur"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Знайти або створити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "搜索或创建"
}
}
}
},
"Search or Create" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hledat / vytvořit"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Suchen"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rechercher ou Créer"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "खोजें या बनाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cerca"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "検索"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zoeken"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Procurar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Найти или создать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ara veya Oluştur"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Знайти або створити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "搜索或创作"
}
}
}
},
"Security" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zabezpečení"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sicherheit"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Securité"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "सुरक्षा"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sicurezza"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "セキュリティ"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Beveiliging"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Segurança"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Безопасность"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Güvenlik"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Безпека"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "安全性"
}
}
}
},
"Select" : {
"comment" : "Main view popover table",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vybrat"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Select"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sélectionner"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "चुने"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Selezionare"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "選択"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Selecteer"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Selecionar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Выбрать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Seç"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вибрати"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "选择"
}
}
}
},
"Settings" : {
"comment" : "Sidebar settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nastavení"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Einstellungen"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Paramètres"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "प्राथमिकताएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Impostazioni"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "設定"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Instellingen"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Definições"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Настройки"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ayarlar"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Налаштування"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "设置"
}
}
}
},
"Share" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sdílet"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Teilen"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Partager"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "शेयर करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Condividi"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "共有"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Delen"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Partilhar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Поделиться"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Paylaş"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Поділитися"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "分享"
}
}
}
},
"Show Folder in Library" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zobrazit složku v Knihovně"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Projekt in Seitenleiste anzeigen"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Afficher le dossier dans la barre latérale"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "लाइब्रेरी में फ़ोल्डर दिखाएँ"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Visualizza cartella nella sidebar"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "サイドバーにフォルダを表示"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Toon map in zijbalk"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar pasta na barra lateral"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показать папку в библиотеке"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Klasörü Kitaplıkta göster"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показати папку на бічній панелі"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "在文库中显示文件夹"
}
}
}
},
"Show Notes in \"Notes\" and \"Todo\"" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zobrazit poznámky v „Poznámkách“ a „Úkolech“"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notizen in \"Notizen\" und \"Todo\" anzeigen"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Afficher les notes dans \"Notes\" et \"Tâches\""
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "\"नोट्स\" और \"टुडू\" में नोट्स दिखाएं"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Visualizza le note negli elenchi \"Note\" e \"Da Fare\""
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "\"すべて\" と \"タスク\" にノートを表示"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Toon notities in \"Notes\" en \"Todo\" lijsten"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mostrar notas nas listas \"Notas\" e \"Tarefas\""
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Показывать в \"Заметках\" и \"Тодо\""
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Notları \"Notlar\" ve \"Yapılacaklar\"da göster"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Включити у \"Нотатки/завдання\""
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "显示笔记在 \"笔记\" 和 \"待办\""
}
}
}
},
"Sort By" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Řadit podle"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sortieren nach"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Trier par"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "इसके अनुसार क्रमबद्ध करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordina per"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "表示順序"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sorteer op"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ordenar por"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сортировать по"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sırala"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сортувати за"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "排序方式"
}
}
}
},
"Sort Direction" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Směr"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Richtung"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Direction de tri"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "क्रमबद्ध दिशा"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Direzione"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "方向"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Richting"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Direcção"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Направление"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sıralama Yönü"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Напрямок"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "方向"
}
}
}
},
"Storage" : {
"comment" : "Settings",
"extractionState" : "manual",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Úložiště"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Speicherort"
}
},
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Storage"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Stockage"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "संग्रहण"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Biblioteca"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ストレージ"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Opslag"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Armazenamento"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Хранилище"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Depolama"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сховище"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "存储"
}
}
}
},
"Support" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Podpora"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Support"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aide"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "सहायता"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Supporto"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "サポート"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ondersteuning"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Suporte"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Поддержка"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Destek"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Підтримка"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "支持"
}
}
}
},
"Tags" : {
"comment" : "Sidebar label",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Značky"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tags"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Étiquettes"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "टैग"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tag"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "タグ"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tags"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Etiquetas"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Теги"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Etiketler"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Мітки"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "标签"
}
}
}
},
"Thanks" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Díky"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dank an"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remerciement "
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "धन्यवाद"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Grazie a"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "次に感謝:"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dankzij"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Graças a"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Спасибо"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Teşekkürler"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Дякую"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "感谢"
}
}
}
},
"Theme" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Motiv"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Thema"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Thème"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "थीम"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tema"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "テーマ"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Thema"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tema"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Тема"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tema"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Тема"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "主题"
}
}
}
},
"Tip: To use old notes, you must decrypt them separately with the old key and encrypt them again." : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tip: pro použití starých poznámek je musíte nejprve zvlášť dešifrovat pomocí starého klíče a pak znovu zašifrovat."
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tipp: Um alte Notizen zu verwenden, müssen Sie sie separat mit dem alten Schlüssel entschlüsseln und erneut verschlüsseln."
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Conseil : pour utiliser d'anciennes notes, vous devez les déchiffrer séparément avec l'ancienne clé et les chiffrer à nouveau."
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "सलाह: पुराने नोट्स का उपयोग करने के लिए, आपको उन्हें पुरानी कुंजी से अलग से डिक्रिप्ट करना होगा और पुनः एन्क्रिप्ट करना होगा।"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Suggerimento: per utilizzare le vecchie note, è necessario decifrarle separatamente con la vecchia chiave e crittografarle nuovamente."
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "補足:古いノートを使うには、古いキーで別途復号化し、再度暗号化する必要があります。"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tip: Om oude notities te gebruiken, moet je ze apart ontsleutelen met de oude sleutel en opnieuw versleutelen."
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sugestão: Para utilizar notas antigas, tem de as desencriptar separadamente com a chave antiga e encriptá-las novamente."
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Совет: Чтобы использовать старые заметки, необходимо отдельно расшифровать их с помощью старого ключа и снова зашифровать."
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "İpucu: Eski notları kullanabilmek için, eski anahtarla ayrı ayrı şifresini çözüp tekrar şifrelemeniz gerekmektedir."
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Порада: Щоб використовувати старі нотатки, ви повинні розшифрувати їх окремо за допомогою старого ключа і зашифрувати знову."
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "小贴士:要使用旧的笔记,您必须用旧的密钥单独解密,并再次加密。"
}
}
}
},
"Title" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nadpis"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Titel"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Titre"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "शीर्षक"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Titolo"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "タイトル"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Titel"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Título"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заголовок"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Başlık"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Заголовком"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "标题"
}
}
}
},
"Todo" : {
"comment" : "Sidebar items\nTodo in sidebar",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Úkoly"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Todo"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tasks"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "टुडू"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Da Fare"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "タスク"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Te Doen"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tarefa"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Задачи"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yapılacaklar"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Завдання"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "待办事项"
}
}
}
},
"Trash" : {
"comment" : "Sidebar label\nTrash in sidebar",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Koš"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Papierkorb"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Corbeille"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "कूडा"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cestino"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ゴミ箱"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Prullenmand"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lixo"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Корзина"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Çöp"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сміття"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "回收站"
}
}
}
},
"Unlock" : {
"comment" : "Main view popover table",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Odemknout"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Entsperren"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Déverrouiller"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "अनलॉक"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sblocca"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "アンロック"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ontgrendel"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Destrancar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Разблокировать"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Kilidi aç"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Розблокувати"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "开锁"
}
}
}
},
"Unpin" : {
"comment" : "Table row action",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Odepnout"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Loslösen"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Désépingler"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "अनपिन"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sblocca"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ピン固定の解除"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "VerwijderPin"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Soltar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Открепить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sabitlemeyi kaldır"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Відкріпити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "取消置顶"
}
}
}
},
"Untagged" : {
"comment" : "Sidebar settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Neoznačené"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ungetaggt"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Non étiqueté"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "बिना टैग"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Senza tag"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "タグなし"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Niet getagd"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sem etiqueta"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Без метки"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Etiketsiz"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Без тегів"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "未标记"
}
}
}
},
"Update" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aktualizovat"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Update"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mise à jour"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "अद्यतन करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aggiornamento"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "アップデート"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Update"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Actualização"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Обновить"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Güncelleme"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Оновити"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "更新"
}
}
}
},
"Update Web Page" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aktualizovat webovou stránku"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Geteilte aktualisieren"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mettre à jour la page Web"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "वेब पेज अपडेट करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aggiorna la pagina web"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web ページの更新"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Webpagina bijwerken"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Atualizar página da Web"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Обновить веб-страницу"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web Sayfasını Güncelle"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Оновити веб-сторінку"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "更新网页"
}
}
}
},
"Use First Line as Title" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Použít první řádek jako nadpis"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Erste Zeile als Titel"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Utiliser la première ligne comme titre"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "शीर्षक के रूप में प्रथम पंक्ति का उपयोग करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Usa la prima riga come titolo"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "最初の行をタイトルとして使用する"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Gebruik eerste regel als titel"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Utilizar a primeira linha como título"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Первая строка как заголовок"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "İlk Satırı Başlık Olarak Kullan"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Перший рядок як заголовок"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "使用第一行作为标题"
}
}
}
},
"Use Inline Tags" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Používat značky mezi textem"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Inlinetags verwenden"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Utiliser les étiquettes en ligne"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "इनलाइन टैग का उपयोग करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Usa tag in linea"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "インラインタグを使用する"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Gebruik inline tags"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Utilizar etiquetas em linha"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Используйте встроенные теги"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Satır İçi Etiketleri Kullan"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Використовувати вбудовані теги"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "使用内联标签"
}
}
}
},
"Use TextBundle info.json to store c/mtime" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Použití TextBundle info.json pro uložení c/mtime"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "TextBundle info.json zum Speichern von c/mtime verwenden"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Utilisez TextBundle info.json pour stocker c/mtime"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "c/mtime संग्रहीत करने के लिए TextBundle info.json का उपयोग करें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Usare TextBundle info.json per memorizzare c/mtime"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "c/mtimeを格納するためにTextBundle info.jsonを使用する。"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Gebruik TextBundle info.json om c/mtime op te slaan"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Utilizar TextBundle info.json para armazenar c/mtime"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Использовать TextBundle info.json для хранения c/mtime"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "C/mtime'ı depolamak için TextBundle info.json'ı kullanın"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Використовувати TextBundle info.json для зберігання c/mtime"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "使用 TextBundle info.json 存储 c/mtime"
}
}
}
},
"Verify Password" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ověřit heslo"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Passwort überprüfen"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vérifier le mot de passe"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "पासवर्ड को सत्यापित करें:"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verifica della password"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "パスワードの確認"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Wachtwoord verifiëren"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verificar a palavra-passe"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Проверить пароль"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Şifreyi Doğrula"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Підтвердіть пароль"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "验证密码"
}
}
}
},
"Version" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verze"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Version"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Version"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "संस्करण"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Versione"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "バージョン"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Versie"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Versão"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Версия"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Versiyon"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Версія"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "版本"
}
}
}
},
"View" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zobrazit"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sicht"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Voir"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "देखें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Visualizzazione"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "表示"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Visie"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Visualizar"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вид"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Görünüm"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вид"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "视图"
}
}
}
},
"View Settings" : {
"comment" : "Main view popover table",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nastavení zobrazení"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Einstellungen"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Paramètres d'affichage"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "प्राथमिकताएं देखें"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Impostazioni vista"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "設定を開く"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bekijk instellingen"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Definições de visualização"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Настройки вида"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Görünüm Ayarları"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Налаштування"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "查看设置"
}
}
}
},
"Visibility" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Viditelnost"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sichtbarkeit"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Visibilité"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "दृश्यता"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Visibilità"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "可視性"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zichtbaarheid"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Visibilidade"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Видимость"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Görünürlük"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Видимість"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "可见性"
}
}
}
},
"Web sharing error" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Chyba sdílení na web"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web sharing error"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Erreur de partage web"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "वेब साझाकरण त्रुटि"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web sharing error"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web sharing error"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web sharing error"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web sharing error"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ошибка публикации веб-страниц"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web paylaşım hatası"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web sharing error"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "网站分享错误"
}
}
}
},
"Website" : {
"comment" : "Settings",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Webová stránka"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Startseite"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Site web"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "वेबसाइट"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Homepage sito web"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ホームページ"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Startpagina"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Página inicial"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сайт"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Web Site"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Домашня сторінка"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "官方网站"
}
}
}
},
"Wrong password" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nesprávné heslo"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Falsches Passwort"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mot de passe erroné"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "गलत पासवर्ड"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Wrong password"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "パスワードが違う"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verkeerd wachtwoord"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Palavra-passe errada"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Неверный пароль"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yanlış şifre"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Неправильний пароль"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "密码错误"
}
}
}
},
"Wrong repeated password" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nesprávné opakované heslo"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Falsches wiederholtes Passwort"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mot de passe répété erroné"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "गलत दोहराया गया पासवर्ड"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Wrong repeated password"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "繰り返しのパスワードが違う"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verkeerd herhaald wachtwoord"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Palavra-passe repetida errada"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Неправильный пароль"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Yanlış tekrarlanan şifre"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Неправильний повторний пароль"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "重复密码错误"
}
}
}
},
"Сlearing history" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Čištění historie"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verlauf löschen"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Effacement de l'historique"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "इतिहास साफ़ किया जा रहा है"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sto imparando la storia"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "履歴の削除"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Geschiedenis leren"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aprendendo a história"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Очистить историю"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Geçmişi temizleme"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Очищення історії"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "清空此笔记的历史版本"
}
}
}
}
},
"version" : "1.0"
}
================================================
FILE: FSNotes iOS/Main.storyboard
================================================
================================================
FILE: FSNotes iOS/MainNavigationController.swift
================================================
//
// MainNavigationController.swift
// FSNotes iOS
//
// Created by Александр on 23.01.2022.
// Copyright © 2022 Oleksandr Glushchenko. All rights reserved.
//
import UIKit
class MainNavigationController: UINavigationController {
override func popViewController(animated: Bool) -> UIViewController? {
UserDefaultsManagement.currentNote = nil
topViewController?.view.endEditing(true)
return super.popViewController(animated: animated)
}
// override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
// super.traitCollectionDidChange(previousTraitCollection)
//
// guard traitCollection.hasDifferentColorAppearance(comparedTo: previousTraitCollection) else { return }
//
// DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
// let evc = UIApplication.getEVC()
//
// evc.editArea.textStorage.updateCheckboxList()
//
// if let previewView = evc.getPreviewView() {
// let funcName = self.traitCollection.userInterfaceStyle == .dark ? "switchToDarkMode" : "switchToLightMode"
// let switchScript = "if (typeof(\(funcName)) == 'function') { \(funcName)(); }"
//
// previewView.evaluateJavaScript(switchScript)
// }
// }
// }
}
================================================
FILE: FSNotes iOS/MoveViewController.swift
================================================
//
// MoveViewController.swift
// FSNotes iOS
//
// Created by Oleksandr Glushchenko on 9/8/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import UIKit
class MoveViewController: UITableViewController {
private var projects: [Project]?
private var selectedNotes: [Note]
private var notesTableView: NotesTableView
init(notes: [Note], notesTableView: NotesTableView) {
self.selectedNotes = notes
self.notesTableView = notesTableView
super.init(style: .plain)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
self.navigationItem.rightBarButtonItem = Buttons.getAdd(target: self, selector: #selector(createFolder))
self.projects = Storage.shared().getProjects()
self.title = NSLocalizedString("Move", comment: "Move view")
super.viewDidLoad()
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
guard let vc = notesTableView.viewDelegate else { return }
if let projects = self.projects {
let project = projects[indexPath.row]
for note in selectedNotes {
let dstURL = project.url.appendingPathComponent(note.name)
if note.project != project {
note.moveImages(to: project)
vc.sidebarTableView.removeTags(in: [note])
guard note.move(to: dstURL) else {
let alert = UIAlertController(title: "Oops 👮♂️", message: NSLocalizedString("File with this name already exist", comment: ""), preferredStyle: UIAlertController.Style.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
self.present(alert, animated: true, completion: nil)
note.moveImages(to: note.project)
return
}
note.moveHistory(src: note.url, dst: dstURL)
note.url = dstURL
note.parseURL()
note.project = project
self.notesTableView.removeRows(notes: [note])
vc.notesTable.insertRows(notes: [note])
}
}
UIApplication.getVC().updateNotesCounter()
}
UIApplication.getEVC().updateTitle()
self.dismiss(animated: true, completion: nil)
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
if let projects = self.projects {
let project = projects[indexPath.row]
if project.isTrash {
cell.textLabel?.text = NSLocalizedString("Trash", comment: "")
} else {
cell.textLabel?.text = project.getNestedLabel()
}
}
return cell
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if let projects = self.projects {
return projects.count
}
return 0
}
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if selectedNotes.count == 1 {
let note = selectedNotes.first!
if let projects = self.projects {
if projects[indexPath.row] == note.project {
cell.accessoryType = .checkmark
}
}
}
}
@objc func createFolder() {
let alertController = UIAlertController(title: NSLocalizedString("Folder name:", comment: ""), message: nil, preferredStyle: .alert)
alertController.addTextField { (textField) in
textField.placeholder = ""
}
let confirmAction = UIAlertAction(title: "OK", style: .default) { (_) in
guard let name = alertController.textFields?[0].text, name.count > 0 else {
return
}
guard let allProjects = self.projects, allProjects.first(where: { $0.label == name } ) == nil else {
let alert = UIAlertController(title: "Oops 👮♂️", message: NSLocalizedString("Folder with this name already exist", comment: ""), preferredStyle: UIAlertController.Style.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
self.present(alert, animated: true, completion: nil)
return
}
guard let newDir = UserDefaultsManagement.storageUrl?.appendingPathComponent(name) else { return }
do {
try FileManager.default.createDirectory(at: newDir, withIntermediateDirectories: false, attributes: nil)
} catch {
print(error)
return
}
if let projects = Storage.shared().insert(url: newDir) {
OperationQueue.main.addOperation {
UIApplication.getVC().sidebarTableView.insertRows(projects: projects)
self.projects?.append(contentsOf: projects)
self.tableView.reloadData()
self.notesTableView.viewDelegate?.sidebarTableView.reloadSidebar()
}
}
}
let cancelAction = UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .cancel) { (_) in }
alertController.addAction(confirmAction)
alertController.addAction(cancelAction)
self.present(alertController, animated: true, completion: nil)
}
@objc func cancel() {
self.dismiss(animated: true, completion: nil)
}
}
================================================
FILE: FSNotes iOS/Preferences/AppIconViewController.swift
================================================
//
// AppIconViewController.swift
// FSNotes iOS
//
// Created by Oleksandr Hlushchenko on 07.04.2023.
// Copyright © 2023 Oleksandr Hlushchenko. All rights reserved.
//
import UIKit
class AppIconViewController: UITableViewController {
enum AppIconRows: Int, CaseIterable {
case modern
case classic
case ny2026
public func getName() -> String {
switch self {
case .modern:
return "Modern"
case .classic:
return "Classic"
case .ny2026:
return "Neo"
}
}
var description : String {
switch self {
case .modern: return "modern"
case .classic: return "classic-2025"
case .ny2026: return "ny-2026"
}
}
static let count: Int = {
var max: Int = 0
while let _ = AppIconRows(rawValue: max) { max += 1 }
return max
}()
}
override func viewDidLoad() {
self.title = NSLocalizedString("Icon", comment: "Settings")
super.viewDidLoad()
}
@objc func cancel() {
self.navigationController?.popViewController(animated: true)
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
for row in AppIconRows.allCases {
if let cell = tableView.cellForRow(at: IndexPath(row: row.rawValue, section: 0)) {
cell.accessoryType = .none
}
}
if let cell = tableView.cellForRow(at: indexPath) {
cell.accessoryType = .checkmark
if let icon = AppIconRows(rawValue: indexPath.row)?.description {
let name = icon == "modern" ? nil : icon
UIApplication.shared.setAlternateIconName(name) { error in
if let error = error {
print("Error setting alternate icon \(String(describing: name)): \(error.localizedDescription)")
} else {
UserDefaultsManagement.appIcon = indexPath.row
}
}
}
}
tableView.deselectRow(at: indexPath, animated: false)
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 120
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
let marginguide = cell.contentView.layoutMarginsGuide
cell.imageView?.translatesAutoresizingMaskIntoConstraints = false
cell.imageView?.topAnchor.constraint(equalTo: marginguide.topAnchor).isActive = true
cell.imageView?.leadingAnchor.constraint(equalTo: marginguide.leadingAnchor).isActive = true
cell.imageView?.heightAnchor.constraint(equalToConstant: 100).isActive = true
cell.imageView?.widthAnchor.constraint(equalToConstant: 100).isActive = true
cell.imageView?.layer.borderColor = UIColor.gray.cgColor
cell.imageView?.layer.borderWidth = 2
cell.imageView?.layer.backgroundColor = UIColor.white.cgColor
cell.imageView?.contentMode = .scaleAspectFill
cell.imageView?.layer.cornerRadius = 20
if let icon = AppIconRows(rawValue: indexPath.row) {
let iconName = "AppIcon" + icon.description.capitalizingFirstLetter()
if let image = UIImage(named: iconName) {
cell.imageView?.image = image
}
cell.textLabel?.text = icon.getName()
}
return cell
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return AppIconRows.count
}
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if indexPath.row == UserDefaultsManagement.appIcon {
cell.accessoryType = .checkmark
}
}
}
================================================
FILE: FSNotes iOS/Preferences/CodeFontViewController.swift
================================================
//
// CodeFontViewController.swift
// FSNotes iOS
//
// Created by Oleksandr Glushchenko on 3/16/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import UIKit
class CodeFontViewController: UITableViewController {
private var fontFamilyNames = [
"Source Code Pro",
"Menlo",
"Courier",
]
override func viewDidLoad() {
title = NSLocalizedString("Font Family", comment: "Settings")
super.viewDidLoad()
}
@objc func cancel() {
self.navigationController?.popViewController(animated: true)
}
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if fontFamilyNames[indexPath.row] == UserDefaultsManagement.codeFont.familyName {
cell.accessoryType = .checkmark
}
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath), let label = cell.textLabel, let fontFamily = label.text {
let fontSize = UserDefaultsManagement.fontSize
if indexPath.row == 0 {
UserDefaultsManagement.codeFontName = "Source Code Pro"
} else if let customFont = UIFont(name: fontFamily, size: CGFloat(fontSize)) {
UserDefaultsManagement.codeFont = customFont
}
MPreviewView.template = nil
UIApplication.getVC().notesTable.reloadData()
self.navigationController?.popViewController(animated: true)
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel?.text = fontFamilyNames[indexPath.row]
return cell
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return fontFamilyNames.count
}
}
================================================
FILE: FSNotes iOS/Preferences/CodeThemeViewController.swift
================================================
//
// CodeThemeViewController.swift
// FSNotes iOS
//
// Created by Oleksandr Glushchenko on 3/16/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import UIKit
class CodeThemeViewController: UITableViewController {
private var themeNames = [
"github",
"solarized",
"atom-one"
]
override func viewDidLoad() {
title = NSLocalizedString("Code Theme", comment: "Settings")
super.viewDidLoad()
}
@objc func cancel() {
self.navigationController?.popViewController(animated: true)
}
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if themeNames[indexPath.row] == UserDefaultsManagement.codeTheme.getName() {
cell.accessoryType = .checkmark
}
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath), let label = cell.textLabel, let theme = label.text {
if let theme = EditorTheme(themeName: theme) {
UserDefaultsManagement.codeTheme = theme
}
NotesTextProcessor.hl = nil
MPreviewView.template = nil
UIApplication.getVC().notesTable.reloadData()
self.navigationController?.popViewController(animated: true)
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel?.text = themeNames[indexPath.row]
return cell
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return themeNames.count
}
}
================================================
FILE: FSNotes iOS/Preferences/DefaultExtensionControllerView.swift
================================================
//
// DefaultExtensionControllerView.swift
// FSNotes iOS
//
// Created by Oleksandr Glushchenko on 2/28/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import UIKit
class DefaultExtensionViewController: UITableViewController {
private var sections = [
NSLocalizedString("Container", comment: "Settings"),
NSLocalizedString("Extension", comment: "Settings"),
NSLocalizedString("Files Naming", comment: "Settings"),
]
private var rowsInSection = [1, 3, 5]
private var extensions = ["markdown", "md", "txt"]
private var naming = [
NSLocalizedString("Autoname By Title", comment: "Settings"),
NSLocalizedString("Auto Rename By Title", comment: "Settings"),
NSLocalizedString("Format: Untitled Note", comment: "Settings"),
NSLocalizedString("Format: yyyyMMddHHmmss", comment: "Settings"),
NSLocalizedString("Format: yyyy-MM-dd hh.mm.ss a", comment: "Settings"),
]
override func viewDidLoad() {
self.title = NSLocalizedString("Files", comment: "Settings")
}
@objc func cancel() {
self.navigationController?.popViewController(animated: true)
}
override func numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return rowsInSection[section]
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sections[section]
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 50
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath), let label = cell.textLabel, let ext = label.text {
if indexPath.section == 1 {
UserDefaultsManagement.noteExtension = ext
UserDefaultsManagement.fileFormat = NoteType.withExt(rawValue: ext)
for index in 0...rowsInSection[indexPath.section] {
let indexPath = IndexPath(row: index, section: 1)
if let cell = tableView.cellForRow(at: indexPath) {
cell.accessoryType = .none
tableView.deselectRow(at: indexPath, animated: false)
}
}
cell.accessoryType = .checkmark
} else if indexPath.section == 2 {
for index in 0...rowsInSection[indexPath.section] {
let indexPath = IndexPath(row: index, section: 2)
if let cell = tableView.cellForRow(at: indexPath) {
cell.accessoryType = .none
tableView.deselectRow(at: indexPath, animated: false)
}
}
if let id = SettingsFilesNaming(rawValue: cell.tag) {
UserDefaultsManagement.naming = id
cell.accessoryType = .checkmark
}
}
}
}
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
guard let text = cell.textLabel?.text else { return }
if indexPath.section == 1 {
if UserDefaultsManagement.noteExtension == text {
cell.accessoryType = .checkmark
} else {
cell.accessoryType = .none
}
} else if indexPath.section == 2 {
if UserDefaultsManagement.naming == SettingsFilesNaming(rawValue: cell.tag) {
cell.accessoryType = .checkmark
} else {
cell.accessoryType = .none
}
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
if indexPath.section == 0 {
let uiSwitch = UISwitch()
uiSwitch.addTarget(self, action: #selector(switchValueDidChange(_:)), for: .valueChanged)
uiSwitch.isOn = UserDefaultsManagement.fileContainer == .textBundle || UserDefaultsManagement.fileContainer == .textBundleV2
cell.textLabel?.text = "Textbundle"
cell.accessoryView = uiSwitch
} else if indexPath.section == 1 {
cell.textLabel?.text = extensions[indexPath.row]
} else if indexPath.section == 2 {
if indexPath.row == 0 {
cell.textLabel?.text = naming[0]
cell.tag = 5
} else {
cell.textLabel?.text = naming[indexPath.row]
cell.tag = indexPath.row
}
}
return cell
}
@objc public func switchValueDidChange(_ sender: UISwitch) {
guard let cell = sender.superview as? UITableViewCell else { return }
guard let uiSwitch = cell.accessoryView as? UISwitch else { return }
UserDefaultsManagement.fileContainer = uiSwitch.isOn ? .textBundleV2 : .none
}
}
================================================
FILE: FSNotes iOS/Preferences/ExternalViewController.swift
================================================
//
// ExternalViewController.swift
// FSNotes iOS
//
// Created by Александр on 20.02.2022.
// Copyright © 2022 Oleksandr Glushchenko. All rights reserved.
//
import Foundation
import UIKit
class ExternalViewController: UIDocumentPickerViewController, UIDocumentPickerDelegate {
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
guard urls.count == 1, let url = urls.first, url.hasDirectoryPath else { return }
guard url.startAccessingSecurityScopedResource() else {
return
}
do {
let bookmarkData = try url.bookmarkData(options: .minimalBookmark, includingResourceValuesForKeys: nil, relativeTo: nil)
SandboxBookmark.sharedInstance().save(data: bookmarkData)
let storage = Storage.shared()
if storage.projectExist(url: url) {
return
}
if let projects = Storage.shared().insert(url: url, bookmark: true) {
OperationQueue.main.addOperation {
UIApplication.getVC().sidebarTableView.insertRows(projects: projects)
_ = UIApplication.getNC()?.popViewController(animated: true)
if !UserDefaultsManagement.sidebarIsOpened {
UIApplication.getVC().openSidebar()
}
if let project = projects.first {
UIApplication.getVC().sidebarTableView.select(project: project)
}
}
}
} catch {
print(error)
}
}
}
================================================
FILE: FSNotes iOS/Preferences/FontViewController.swift
================================================
//
// FontViewController.swift
// FSNotes iOS
//
// Created by Oleksandr Glushchenko on 3/16/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import UIKit
class FontViewController: UITableViewController {
private var fontFamilyNames = [
"System",
"Avenir Next",
"Georgia",
"Helvetica Neue",
"Menlo",
"Courier",
"Palatino"
]
override func viewDidLoad() {
title = NSLocalizedString("Font Family", comment: "Settings")
super.viewDidLoad()
}
@objc func cancel() {
self.navigationController?.popViewController(animated: true)
}
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if UserDefaultsManagement.fontName == nil && indexPath.row == 0 {
cell.accessoryType = .checkmark
}
if fontFamilyNames[indexPath.row] == UserDefaultsManagement.noteFont.familyName {
cell.accessoryType = .checkmark
}
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath), let label = cell.textLabel, let fontFamily = label.text {
let fontSize = UserDefaultsManagement.fontSize
if indexPath.row == 0 {
UserDefaultsManagement.fontName = nil
} else if let customFont = UIFont(name: fontFamily, size: CGFloat(fontSize)) {
UserDefaultsManagement.noteFont = customFont
}
MPreviewView.template = nil
UIApplication.getVC().notesTable.reloadData()
self.navigationController?.popViewController(animated: true)
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel?.text = fontFamilyNames[indexPath.row]
return cell
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return fontFamilyNames.count
}
}
================================================
FILE: FSNotes iOS/Preferences/GitTableViewCell.swift
================================================
//
// GitTableCellView.swift
// FSNotes iOS
//
// Created by Oleksandr Hlushchenko on 01.03.2023.
// Copyright © 2023 Oleksandr Hlushchenko. All rights reserved.
//
import Foundation
import UIKit
class GitTableViewCell: UITableViewCell {
public var project: Project?
@IBOutlet weak var removeButton: UIButton!
@IBOutlet weak var cloneButton: UIButton!
@IBOutlet weak var activity: UIActivityIndicatorView!
}
================================================
FILE: FSNotes iOS/Preferences/GitViewController.swift
================================================
//
// GitViewController.swift
// FSNotes iOS
//
// Created by Oleksandr Hlushchenko on 05.02.2023.
// Copyright © 2023 Oleksandr Hlushchenko. All rights reserved.
//
import UIKit
import CoreServices
class GitViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var tableView: UITableView!
enum GitSection: Int, CaseIterable {
case automation
case credentials
case origin
case logs
var title: String {
switch self {
case .automation: return "Automation"
case .credentials: return "Credentials"
case .origin: return "Origin"
case .logs: return "Status"
}
}
}
private var hasActiveGit: Bool = false
private var progress: GitProgress?
private var project: Project?
public var activity: UIActivityIndicatorView?
public var leftButton: UIButton?
public var rightButton: UIButton?
public var logTextField: UITextField?
public func setProject(_ project: Project) {
self.project = project
}
override func viewDidLoad() {
self.title = NSLocalizedString("Git", comment: "Settings")
navigationItem.largeTitleDisplayMode = .always
tableView.delegate = self
tableView.dataSource = self
super.viewDidLoad()
setupKeyboardObservers()
tableView.keyboardDismissMode = .interactive
}
override func viewWillAppear(_ animated: Bool) {
UIApplication.shared.isIdleTimerDisabled = true
DispatchQueue.main.async {
self.updateButtons(isActive: self.hasActiveGit)
if let status = self.project?.gitStatus {
self.logTextField?.text = status
}
}
}
override func viewWillDisappear(_ animated: Bool) {
UIApplication.shared.isIdleTimerDisabled = false
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return GitSection(rawValue: section)?.title
}
@objc func cancel() {
self.navigationController?.popViewController(animated: true)
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.section == GitSection.credentials.rawValue && indexPath.row == 0 {
changePrivateKey(tableView: tableView, indexPath: indexPath)
}
if indexPath.section == GitSection.credentials.rawValue && indexPath.row == 1 {
changePublicKey(tableView: tableView, indexPath: indexPath)
}
tableView.deselectRow(at: indexPath, animated: false)
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 50
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let project = project else { return UITableViewCell() }
if indexPath.section == GitSection.automation.rawValue {
let cell = UITableViewCell(style: .value1, reuseIdentifier: nil)
if indexPath.row == 0 {
cell.textLabel?.text = NSLocalizedString("Pull (every 30 sec)", comment: "")
let uiSwitch = UISwitch()
uiSwitch.addTarget(self, action: #selector(autoPullDidChange(_:)), for: .valueChanged)
uiSwitch.isOn = project.settings.gitAutoPull
cell.accessoryView = uiSwitch
}
return cell
}
// Passphrase and origin textfields
if indexPath.section == GitSection.credentials.rawValue && indexPath.row == 2 || (
indexPath.section == GitSection.origin.rawValue && indexPath.row == 0 ||
indexPath.section == GitSection.logs.rawValue && indexPath.row == 0
) {
let cell = UITableViewCell(style: .value1, reuseIdentifier: nil)
let textField = UITextField()
textField.textColor = UIColor.blackWhite
// Passphrase
if indexPath.section == GitSection.credentials.rawValue && indexPath.row == 2 {
cell.textLabel?.text = NSLocalizedString("Passphrase", comment: "")
textField.isSecureTextEntry = true
textField.addTarget(self, action: #selector(passphraseDidChange), for: .editingChanged)
textField.placeholder = "(optional)"
textField.text = project.settings.gitPrivateKeyPassphrase
}
// Origin
if indexPath.section == GitSection.origin.rawValue && indexPath.row == 0 {
textField.addTarget(self, action: #selector(originDidChange), for: .editingChanged)
textField.placeholder = "git@github.com:username/example.git"
textField.text = project.settings.gitOrigin ?? ""
}
// Logs
if indexPath.section == GitSection.logs.rawValue && indexPath.row == 0 {
textField.placeholder = "no data"
textField.isEnabled = false
logTextField = textField
progress = GitProgress(statusTextField: textField, project: project)
// Global instance
AppDelegate.gitProgress = progress
}
textField.translatesAutoresizingMaskIntoConstraints = false
textField.textAlignment = .right
cell.contentView.addSubview(textField)
cell.addConstraint(NSLayoutConstraint(item: textField, attribute: .leading, relatedBy: .equal, toItem: cell.textLabel, attribute: .trailing, multiplier: 1, constant: 8))
cell.addConstraint(NSLayoutConstraint(item: textField, attribute: .top, relatedBy: .equal, toItem: cell.contentView, attribute: .top, multiplier: 1, constant: 8))
cell.addConstraint(NSLayoutConstraint(item: textField, attribute: .bottom, relatedBy: .equal, toItem: cell.contentView, attribute: .bottom, multiplier: 1, constant: -8))
cell.addConstraint(NSLayoutConstraint(item: textField, attribute: .trailing, relatedBy: .equal, toItem: cell.contentView, attribute: .trailing, multiplier: 1, constant: -8))
return cell
}
// Clone button
if indexPath.section == GitSection.origin.rawValue && indexPath.row == 1 {
let cell = tableView.dequeueReusableCell(withIdentifier: "gitTableViewCell", for: indexPath) as! GitTableViewCell
cell.selectionStyle = .none
cell.cloneButton.addTarget(self, action: #selector(repoPressed), for: .touchUpInside)
cell.removeButton.addTarget(self, action: #selector(removePressed), for: .touchUpInside)
leftButton = cell.cloneButton
rightButton = cell.removeButton
activity = cell.activity
activity?.isHidden = true
activity?.startAnimating()
return cell
}
let cell = UITableViewCell(style: .value1, reuseIdentifier: nil)
// Private key
if indexPath.section == GitSection.credentials.rawValue && indexPath.row == 0 {
cell.textLabel?.text = NSLocalizedString("Private Key", comment: "")
cell.detailTextLabel?.text = NSLocalizedString("...", comment: "")
if project.settings.gitPrivateKey != nil {
cell.detailTextLabel?.text = NSLocalizedString("✅ - ", comment: "")
let accessoryButton = UIButton(type: .system)
accessoryButton.addTarget(self, action: #selector(deletePrivateKey(sender:)), for: .touchUpInside)
accessoryButton.setImage(UIImage(systemName: "trash"), for: .normal)
accessoryButton.frame = CGRect(x: 0, y: 0, width: 35, height: 35)
cell.accessoryView = accessoryButton
}
}
// Public key
if indexPath.section == GitSection.credentials.rawValue && indexPath.row == 1 {
cell.textLabel?.text = NSLocalizedString("Public Key (optional)", comment: "")
cell.detailTextLabel?.text = NSLocalizedString("...", comment: "")
if project.settings.gitPublicKey != nil {
cell.detailTextLabel?.text = NSLocalizedString("✅ - ", comment: "")
let accessoryButton = UIButton(type: .system)
accessoryButton.addTarget(self, action: #selector(deletePublicKey(sender:)), for: .touchUpInside)
accessoryButton.setImage(UIImage(systemName: "trash"), for: .normal)
accessoryButton.frame = CGRect(x: 0, y: 0, width: 35, height: 35)
cell.accessoryView = accessoryButton
}
}
return cell
}
func numberOfSections(in tableView: UITableView) -> Int {
return GitSection.allCases.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return 1
}
if section == 1 {
return 3
}
if section == 2 {
return 2
}
return 1
}
private lazy var documentPickerPrivateKey: UIDocumentPickerViewController = {
let documentPicker = UIDocumentPickerViewController(forOpeningContentTypes: [.data], asCopy: true)
documentPicker.delegate = self
documentPicker.allowsMultipleSelection = false
documentPicker.modalPresentationStyle = .formSheet
return documentPicker
}()
private lazy var documentPickerPublicKey: UIDocumentPickerViewController = {
let documentPicker = UIDocumentPickerViewController(forOpeningContentTypes: [.data], asCopy: true)
documentPicker.delegate = self
documentPicker.allowsMultipleSelection = false
documentPicker.modalPresentationStyle = .formSheet
return documentPicker
}()
private func changePrivateKey(tableView: UITableView, indexPath: IndexPath) {
present(documentPickerPrivateKey, animated: true, completion: nil)
}
private func changePublicKey(tableView: UITableView, indexPath: IndexPath) {
present(documentPickerPublicKey, animated: true, completion: nil)
}
@objc func deletePrivateKey(sender: UIButton) {
guard let project = project else { return }
project.settings.gitPrivateKey = nil
project.saveSettings()
if let privateUrl = project.getSSHKeyUrl(),
FileManager.default.fileExists(atPath: privateUrl.path) {
try? FileManager.default.removeItem(at: privateUrl)
}
guard let cell = sender.superview as? UITableViewCell,
let tableView = cell.superview as? UITableView,
let indexPath = tableView.indexPath(for: cell) else { return }
tableView.reloadRows(at: [indexPath], with: .none)
}
@objc func deletePublicKey(sender: UIButton) {
guard let project = project else { return }
project.settings.gitPublicKey = nil
project.saveSettings()
if let pubUrl = project.getSSHKeyUrl()?.appendingPathExtension("pub"),
FileManager.default.fileExists(atPath: pubUrl.path) {
try? FileManager.default.removeItem(at: pubUrl)
}
guard let cell = sender.superview as? UITableViewCell,
let tableView = cell.superview as? UITableView,
let indexPath = tableView.indexPath(for: cell) else { return }
tableView.reloadRows(at: [indexPath], with: .none)
}
@objc func passphraseDidChange(sender: UITextField) {
guard let text = sender.text else { return }
guard let project = project else { return }
project.settings.gitPrivateKeyPassphrase = text
project.saveSettings()
}
@objc func originDidChange(sender: UITextField) {
guard let project = project, let origin = sender.text else { return }
project.settings.setOrigin(origin)
project.saveSettings()
updateButtons()
}
@objc func removePressed(sender: UIButton) {
guard let project = project else { return }
project.removeSSHKey()
project.removeRepository()
rightButton?.isEnabled = false
progress?.log(message: "git repository removed")
updateButtons()
}
@objc func repoPressed(sender: UIButton) {
guard let project = project else { return }
let action = project.getRepositoryState()
updateButtons(isActive: true)
UIApplication.shared.isIdleTimerDisabled = true
UIApplication.getVC().gitQueue.addOperation({
defer {
DispatchQueue.main.async {
UIApplication.shared.isIdleTimerDisabled = false
UIApplication.getVC().scheduledGitPull()
self.updateButtons(isActive: false)
}
}
if let message = project.gitDo(action, progress: self.progress) {
DispatchQueue.main.async {
self.errorAlert(title: "git error", message: message)
// Refresh local files
if action == .pullPush && !UserDefaultsManagement.iCloudDrive {
UIApplication.getVC().checkNew()
}
}
}
})
}
public func errorAlert(title: String, message: String) {
DispatchQueue.main.async {
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
let okAction = UIAlertAction(title: "OK", style: .cancel) { (_) in }
alertController.addAction(okAction)
self.present(alertController, animated: true, completion: nil)
}
}
public func updateButtons(isActive: Bool? = nil) {
guard let project = project else { return }
if let isActive = isActive {
hasActiveGit = isActive
leftButton?.isEnabled = !isActive
activity?.isHidden = !isActive
}
rightButton?.isEnabled = project.hasRepository()
let state = project.getRepositoryState()
leftButton?.setTitle(state.title, for: .normal)
}
@objc public func autoPullDidChange(_ sender: UISwitch) {
guard let cell = sender.superview as? UITableViewCell else { return }
guard let uiSwitch = cell.accessoryView as? UISwitch else { return }
guard let project = project else { return }
project.settings.gitAutoPull = uiSwitch.isOn
project.saveSettings()
}
public func setProgress(message: String) {
progress?.log(message: message)
}
private func setupKeyboardObservers() {
NotificationCenter.default.addObserver(
self,
selector: #selector(keyboardWillShow),
name: UIResponder.keyboardWillShowNotification,
object: nil
)
NotificationCenter.default.addObserver(
self,
selector: #selector(keyboardWillHide),
name: UIResponder.keyboardWillHideNotification,
object: nil
)
}
@objc private func keyboardWillShow(_ notification: Notification) {
guard let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return }
let keyboardHeight = keyboardFrame.height
let bottomSafeArea = view.safeAreaInsets.bottom
UIView.animate(withDuration: 0.3) {
self.tableView.contentInset.bottom = keyboardHeight - bottomSafeArea
self.tableView.verticalScrollIndicatorInsets.bottom = keyboardHeight - bottomSafeArea
}
}
@objc private func keyboardWillHide(_ notification: Notification) {
UIView.animate(withDuration: 0.3) {
self.tableView.contentInset.bottom = 0
self.tableView.verticalScrollIndicatorInsets.bottom = 0
}
}
deinit {
NotificationCenter.default.removeObserver(self)
}
}
extension GitViewController: UIDocumentPickerDelegate, UINavigationControllerDelegate {
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
guard let url = urls.first else { return }
guard let data = try? Data(contentsOf: url) else { return }
guard let project = project else { return }
if controller == documentPickerPrivateKey {
project.settings.gitPrivateKey = data
}
if controller == documentPickerPublicKey {
project.settings.gitPublicKey = data
}
project.saveSettings()
tableView.reloadData()
}
func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
controller.dismiss(animated: true, completion: nil)
}
}
================================================
FILE: FSNotes iOS/Preferences/LanguageViewController.swift
================================================
//
// LanguageViewController.swift
// FSNotes iOS
//
// Created by Oleksandr Glushchenko on 3/12/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import UIKit
class LanguageViewController: UITableViewController {
private var languages: [String]? = []
override func viewDidLoad() {
for im in UITextInputMode.activeInputModes {
if let lang = im.primaryLanguage {
self.languages?.append(lang)
}
}
self.title = NSLocalizedString("Default Keyboard", comment: "Settings")
super.viewDidLoad()
}
@objc func cancel() {
self.navigationController?.popViewController(animated: true)
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
UserDefaultsManagement.defaultKeyboard = languages?[ indexPath.row]
self.navigationController?.popViewController(animated: true)
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel?.text = languages?[indexPath.row]
return cell
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if let l = languages {
return l.count
}
return 0
}
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
guard let language = UserDefaultsManagement.defaultKeyboard else { return }
if languages?[indexPath.row] == language {
cell.accessoryType = .checkmark
}
}
}
================================================
FILE: FSNotes iOS/Preferences/ProViewController.swift
================================================
//
// ProViewController.swift
// FSNotes iOS
//
// Created by Александр on 19.02.2022.
// Copyright © 2022 Oleksandr Glushchenko. All rights reserved.
//
import UIKit
class ProViewController: UITableViewController {
private var sections = [
NSLocalizedString("+", comment: "Settings"),
NSLocalizedString("View", comment: "Settings"),
]
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sections[section]
}
private var rows = [
[
NSLocalizedString("Default Keyboard", comment: ""),
NSLocalizedString("Use Inline Tags", comment: ""),
NSLocalizedString("Use TextBundle info.json to store c/mtime", comment: "")
], [
NSLocalizedString("Sort By", comment: ""),
NSLocalizedString("Library", comment: "")
]
]
override func viewDidLoad() {
self.title = NSLocalizedString("Advanced", comment: "Settings")
super.viewDidLoad()
}
@objc func cancel() {
self.navigationController?.popViewController(animated: true)
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.section == 1 {
if indexPath.row == 0 {
self.navigationController?.pushViewController(SortByViewController(), animated: true)
} else {
self.navigationController?.pushViewController(SidebarViewController(), animated: true)
}
}
if indexPath.section == 0, indexPath.row == 0 {
self.navigationController?.pushViewController(LanguageViewController(), animated: true)
}
tableView.deselectRow(at: indexPath, animated: false)
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let uiSwitch = UISwitch()
uiSwitch.addTarget(self, action: #selector(switchValueDidChange(_:)), for: .valueChanged)
let cell = UITableViewCell()
cell.textLabel?.text = rows[indexPath.section][indexPath.row]
if indexPath.section == 0 {
switch indexPath.row {
case 1:
cell.accessoryView = uiSwitch
uiSwitch.isOn = UserDefaultsManagement.inlineTags
break
case 2:
cell.accessoryView = uiSwitch
uiSwitch.isOn = UserDefaultsManagement.useTextBundleMetaToStoreDates
break
default:
break
}
}
if indexPath.section == 1 {
cell.accessoryType = .disclosureIndicator
}
return cell
}
override func numberOfSections(in tableView: UITableView) -> Int {
return rows.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return rows[section].count
}
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if indexPath.row == 0 {
cell.accessoryType = .disclosureIndicator
}
}
@objc public func switchValueDidChange(_ sender: UISwitch) {
guard let cell = sender.superview as? UITableViewCell,
let tableView = cell.superview as? UITableView,
let indexPath = tableView.indexPath(for: cell) else { return }
switch indexPath.row {
case 1:
guard let uiSwitch = cell.accessoryView as? UISwitch else { return }
UserDefaultsManagement.inlineTags = uiSwitch.isOn
let vc = UIApplication.getVC()
if UserDefaultsManagement.inlineTags {
vc.sidebarTableView.loadAllTags()
} else {
vc.sidebarTableView.unloadAllTags()
}
vc.resizeSidebar(withAnimation: true)
case 2:
guard let uiSwitch = cell.accessoryView as? UISwitch else { return }
UserDefaultsManagement.useTextBundleMetaToStoreDates = uiSwitch.isOn
default:
return
}
}
private func autoVersioningPrompt() {
let title = NSLocalizedString("Сlearing history", comment: "")
let message = NSLocalizedString("Are you sure you want to delete the history of all notes?", comment: "")
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default) { (_) in
let revisions = Storage.shared().getRevisionsHistoryDocumentsSupport()
do {
try FileManager.default.removeItem(at: revisions)
} catch {
print("History clear: \(error)")
}
self.dismiss(animated: true)
})
let cancel = NSLocalizedString("Cancel", comment: "")
alert.addAction(UIAlertAction(title: cancel, style: .cancel, handler: { (action: UIAlertAction!) in
}))
self.present(alert, animated: true, completion: nil)
}
}
================================================
FILE: FSNotes iOS/Preferences/ProjectSettingsViewController.swift
================================================
//
// ProjectSettingsViewController.swift
// FSNotes iOS
//
// Created by Oleksandr Glushchenko on 9/20/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import UIKit
class ProjectSettingsViewController: UITableViewController {
private var dismiss: Bool = false
private var project: Project
private var sections = [
NSLocalizedString("Sort By", comment: ""),
NSLocalizedString("Sort Direction", comment: ""),
NSLocalizedString("Visibility", comment: ""),
NSLocalizedString("Notes List", comment: "")
]
private var rowsInSections = [4, 2, 2, 1]
init(project: Project, dismiss: Bool = false) {
self.project = project
self.dismiss = dismiss
super.init(style: .grouped)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
if dismiss {
self.navigationItem.rightBarButtonItem = Buttons.getDone(target: self, selector: #selector(close))
}
self.title = project.getFullLabel()
super.viewDidLoad()
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let vc = UIApplication.getVC()
if let cell = tableView.cellForRow(at: indexPath) {
if indexPath.section == 0x00 {
for row in 0...rowsInSections[indexPath.section] {
let cell = tableView.cellForRow(at: IndexPath(row: row, section: indexPath.section))
cell?.accessoryType = .none
}
if let sort = SortBy(rawValue: cell.reuseIdentifier!) {
self.project.settings.sortBy = sort
vc.buildSearchQuery()
vc.reloadNotesTable()
}
if cell.accessoryType == .none {
cell.accessoryType = .checkmark
} else {
cell.accessoryType = .none
}
}
if indexPath.section == 0x01 {
for row in 0...rowsInSections[indexPath.section] {
let cell = tableView.cellForRow(at: IndexPath(row: row, section: indexPath.section))
cell?.accessoryType = .none
}
if let sort = SortDirection(rawValue: cell.reuseIdentifier!) {
self.project.settings.sortDirection = sort
vc.buildSearchQuery()
vc.reloadNotesTable()
}
if cell.accessoryType == .none {
cell.accessoryType = .checkmark
} else {
cell.accessoryType = .none
}
}
}
project.saveSettings()
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return rowsInSections[section]
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 4
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 50
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sections[section]
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let uiSwitch = UISwitch()
uiSwitch.addTarget(self, action: #selector(switchValueDidChange(_:)), for: .valueChanged)
var cell = UITableViewCell()
if indexPath.section == 0x00 {
switch indexPath.row {
case 0:
cell = UITableViewCell(style: .default, reuseIdentifier: "none")
cell.textLabel?.text = NSLocalizedString("None", comment: "")
if project.settings.sortBy.rawValue == "none" {
cell.accessoryType = .checkmark
}
break
case 1:
cell = UITableViewCell(style: .default, reuseIdentifier: "modificationDate")
cell.textLabel?.text = NSLocalizedString("Modification Date", comment: "")
if project.settings.sortBy.rawValue == "modificationDate" {
cell.accessoryType = .checkmark
}
break
case 2:
cell = UITableViewCell(style: .default, reuseIdentifier: "creationDate")
cell.textLabel?.text = NSLocalizedString("Creation Date", comment: "")
if project.settings.sortBy.rawValue == "creationDate" {
cell.accessoryType = .checkmark
}
break
case 3:
cell = UITableViewCell(style: .default, reuseIdentifier: "title")
cell.textLabel?.text = NSLocalizedString("Title", comment: "")
if project.settings.sortBy.rawValue == "title" {
cell.accessoryType = .checkmark
}
break
default:
break
}
}
if indexPath.section == 0x01 {
switch indexPath.row {
case 0:
cell = UITableViewCell(style: .default, reuseIdentifier: "asc")
cell.textLabel?.text = NSLocalizedString("Ascending", comment: "")
if project.settings.sortDirection.rawValue == "asc" {
cell.accessoryType = .checkmark
}
break
case 1:
cell = UITableViewCell(style: .default, reuseIdentifier: "desc")
cell.textLabel?.text = NSLocalizedString("Descending", comment: "")
if project.settings.sortDirection.rawValue == "desc" {
cell.accessoryType = .checkmark
}
break
default:
break
}
}
if indexPath.section == 0x02 {
switch indexPath.row {
case 0:
cell.accessoryView = uiSwitch
uiSwitch.isOn = project.settings.showInCommon
uiSwitch.isEnabled =
!project.isDefault
&& !project.isTrash
&& !project.isVirtual
cell.textLabel?.text = NSLocalizedString("Show Notes in \"Notes\" and \"Todo\"", comment: "")
case 1:
cell.accessoryView = uiSwitch
uiSwitch.isOn = project.settings.showInSidebar
uiSwitch.isEnabled =
!project.isDefault
&& !project.isTrash
&& !project.isVirtual
cell.textLabel?.text = NSLocalizedString("Show Folder in Library", comment: "")
default:
return cell
}
}
if indexPath.section == 0x03 {
cell.accessoryView = uiSwitch
uiSwitch.isOn = project.settings.isFirstLineAsTitle()
uiSwitch.isEnabled = !project.isVirtual
cell.textLabel?.text = NSLocalizedString("Use First Line as Title", comment: "")
}
return cell
}
@objc public func switchValueDidChange(_ sender: UISwitch) {
guard let cell = sender.superview as? UITableViewCell,
let tableView = cell.superview as? UITableView,
let indexPath = tableView.indexPath(for: cell) else { return }
let vc = UIApplication.getVC()
if indexPath.section == 0x02 {
if indexPath.row == 0x00 {
guard let uiSwitch = cell.accessoryView as? UISwitch else { return }
self.project.settings.showInCommon = uiSwitch.isOn
vc.reloadNotesTable()
} else {
guard let uiSwitch = cell.accessoryView as? UISwitch else { return }
self.project.settings.showInSidebar = uiSwitch.isOn
OperationQueue.main.addOperation {
if !uiSwitch.isOn {
let at = IndexPath(row: 0, section: 0)
vc.sidebarTableView.tableView(vc.sidebarTableView, didSelectRowAt: at)
vc.sidebarTableView.removeRows(projects: [self.project])
} else {
vc.sidebarTableView.insertRows(projects: [self.project])
}
}
}
} else if indexPath.section == 0x03 {
guard let uiSwitch = cell.accessoryView as? UISwitch else { return }
project.settings.firstLineAsTitle = uiSwitch.isOn
let notes = Storage.shared().getNotesBy(project: project)
for note in notes {
note.invalidateCache()
}
vc.reloadNotesTable()
}
project.saveSettings()
}
@objc func cancel() {
navigationController?.popViewController(animated: true)
}
@objc func close() {
dismiss(animated: true, completion: nil)
}
}
================================================
FILE: FSNotes iOS/Preferences/ProjectsViewController.swift
================================================
//
// ProjectsViewController.swift
// FSNotes iOS
//
// Created by Oleksandr Glushchenko on 9/20/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import UIKit
import CoreServices
import UniformTypeIdentifiers
class ProjectsViewController: UITableViewController, UIDocumentPickerDelegate {
private var projects: [Project]
init() {
let storage = Storage.shared()
self.projects = storage.getProjects()
super.init(style: .plain)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
let addProject = Buttons.getAdd(target: self, selector: #selector(newAlert))
var buttons = [UIBarButtonItem]()
buttons.append(addProject)
// if #available(iOS 13.0, *) {
// let external = Buttons.getAttach(target: self, selector: #selector(attachExternal))
//
// buttons.append(external)
// }
self.navigationItem.rightBarButtonItems = buttons
self.projects = Storage.shared().getProjects()
self.title = NSLocalizedString("Folders", comment: "Settings")
super.viewDidLoad()
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let project = self.projects[indexPath.row]
let controller = ProjectSettingsViewController(project: project)
self.navigationController?.pushViewController(controller, animated: true)
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
if self.projects.count > 0 {
let project = projects[indexPath.row]
if project.isTrash {
cell.textLabel?.text = NSLocalizedString("Trash", comment: "")
} else {
cell.textLabel?.text = project.getNestedLabel()
}
}
cell.accessoryType = .disclosureIndicator
return cell
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.projects.count
}
override func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
return .none
}
override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let project = self.projects[indexPath.row]
if project.isDefault {
return nil
}
if project.isTrash {
return nil
}
let deleteAction = UIContextualAction(style: .destructive, title: NSLocalizedString("Delete", comment: "")) { (action, view, completionHandler) in
self.delete(project: project)
completionHandler(true)
}
deleteAction.backgroundColor = UIColor(red:0.93, green:0.31, blue:0.43, alpha:1.0)
let configuration = UISwipeActionsConfiguration(actions: [deleteAction])
configuration.performsFirstActionWithFullSwipe = true // This mimics the full swipe behavior if needed
return configuration
}
@objc func cancel() {
self.navigationController?.popViewController(animated: true)
}
@objc func newAlert() {
let alertController = UIAlertController(title: NSLocalizedString("Folder name:", comment: ""), message: nil, preferredStyle: .alert)
alertController.addTextField { (textField) in
textField.placeholder = ""
}
let confirmAction = UIAlertAction(title: "OK", style: .default) { (_) in
guard let name = alertController.textFields?[0].text, name.count > 0 else {
return
}
guard self.projects.first(where: { $0.label == name } ) == nil else {
let alert = UIAlertController(title: "Oops 👮♂️", message: NSLocalizedString("Folder with this name already exist", comment: ""), preferredStyle: UIAlertController.Style.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
self.present(alert, animated: true, completion: nil)
return
}
guard let newDir = UserDefaultsManagement.storageUrl?.appendingPathComponent(name, isDirectory: true) else { return }
do {
try FileManager.default.createDirectory(at: newDir, withIntermediateDirectories: false, attributes: nil)
} catch {
print(error)
return
}
if let projects = Storage.shared().insert(url: newDir) {
self.tableView.reloadData()
OperationQueue.main.addOperation {
UIApplication.getVC().sidebarTableView.insertRows(projects: projects)
}
}
}
let cancelAction = UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .cancel) { (_) in }
alertController.addAction(confirmAction)
alertController.addAction(cancelAction)
self.present(alertController, animated: true, completion: nil)
}
@objc func attachExternal() {
let documentPicker = UIDocumentPickerViewController(forOpeningContentTypes: [UTType.folder])
documentPicker.delegate = self
present(documentPicker, animated: true, completion: nil)
}
private func delete(project: Project) {
if project.isBookmark {
self.removeProject(project: project)
SandboxBookmark.sharedInstance().remove(url: project.url)
return
}
let message = "Are you sure you want to remove project \"\(project.getFullLabel())\" and all files inside?"
let alertController = UIAlertController(title: NSLocalizedString("Project removing ❌", comment: ""), message: message, preferredStyle: .alert)
let confirmAction = UIAlertAction(title: "OK", style: .default) { (_) in
project.remove()
self.removeProject(project: project)
}
let cancelAction = UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .cancel) { (_) in }
alertController.addAction(confirmAction)
alertController.addAction(cancelAction)
self.present(alertController, animated: true, completion: nil)
}
private func removeProject(project: Project) {
if let i = self.projects.firstIndex(of: project) {
self.projects.remove(at: i)
}
self.tableView.reloadData()
Storage.shared().removeBy(project: project)
let vc = UIApplication.getVC()
vc.reloadNotesTable() {
OperationQueue.main.addOperation {
vc.sidebarTableView.removeRows(projects: [project])
}
}
}
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
guard urls.count == 1, let url = urls.first, url.hasDirectoryPath else { return }
guard url.startAccessingSecurityScopedResource() else {
return
}
do {
let bookmarkData = try url.bookmarkData(options: .minimalBookmark, includingResourceValuesForKeys: nil, relativeTo: nil)
SandboxBookmark.sharedInstance().save(data: bookmarkData)
if let projects = Storage.shared().insert(url: url) {
OperationQueue.main.addOperation {
UIApplication.getVC().sidebarTableView.insertRows(projects: projects)
self.projects.append(contentsOf: projects)
self.tableView.reloadData()
}
}
} catch {
print(error)
}
}
}
================================================
FILE: FSNotes iOS/Preferences/SecurityViewController.swift
================================================
//
// SecurityViewController.swift
// FSNotes iOS
//
// Created by Oleksandr Hlushchenko on 08.04.2023.
// Copyright © 2023 Oleksandr Hlushchenko. All rights reserved.
//
import UIKit
class SecurityViewController: UITableViewController {
lazy var saveButton: UIButton = {
let button : UIButton = UIButton(type: UIButton.ButtonType.custom) as UIButton
button.backgroundColor = UIColor.systemBlue
button.layer.cornerRadius = 10
button.addTarget(self, action: #selector(saveButtonClicked), for: .touchUpInside)
button.setTitle(NSLocalizedString("Save", comment: ""), for: UIControl.State.normal)
button.contentEdgeInsets = UIEdgeInsets(top: 10, left: 25, bottom: 10, right: 25)
return button
}()
var passwordTextField: UITextField?
var verifyPasswordTextField: UITextField?
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return NSLocalizedString("Master", comment: "Settings")
}
override func viewDidLoad() {
self.title = NSLocalizedString("Security", comment: "Settings")
super.viewDidLoad()
}
@objc func cancel() {
self.navigationController?.popViewController(animated: true)
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .value1, reuseIdentifier: nil)
let textField = UITextField()
var password = String()
do {
let item = KeychainPasswordItem(service: KeychainConfiguration.serviceName, account: "Master Password")
password = try item.readPassword()
} catch {
print(error)
}
textField.text = password
if indexPath.row == 0 {
cell.textLabel?.text = NSLocalizedString("Password", comment: "")
textField.placeholder = "Required"
passwordTextField = textField
}
if indexPath.row == 1 {
cell.textLabel?.text = NSLocalizedString("Verify Password", comment: "")
textField.placeholder = "Required"
verifyPasswordTextField = textField
}
if indexPath.row == 2 {
let cell: UITableViewCell = UITableViewCell()
cell.selectionStyle = .none
cell.contentView.addSubview(saveButton)
saveButton.translatesAutoresizingMaskIntoConstraints = false
saveButton.centerXAnchor.constraint(equalTo: cell.centerXAnchor).isActive = true
saveButton.centerYAnchor.constraint(equalTo: cell.centerYAnchor).isActive = true
return cell
}
textField.isSecureTextEntry = true
textField.translatesAutoresizingMaskIntoConstraints = false
textField.textAlignment = .right
cell.contentView.addSubview(textField)
cell.addConstraint(NSLayoutConstraint(item: textField, attribute: .leading, relatedBy: .equal, toItem: cell.textLabel, attribute: .trailing, multiplier: 1, constant: 8))
cell.addConstraint(NSLayoutConstraint(item: textField, attribute: .top, relatedBy: .equal, toItem: cell.contentView, attribute: .top, multiplier: 1, constant: 8))
cell.addConstraint(NSLayoutConstraint(item: textField, attribute: .bottom, relatedBy: .equal, toItem: cell.contentView, attribute: .bottom, multiplier: 1, constant: -8))
cell.addConstraint(NSLayoutConstraint(item: textField, attribute: .trailing, relatedBy: .equal, toItem: cell.contentView, attribute: .trailing, multiplier: 1, constant: -8))
return cell
}
@objc func saveButtonClicked(sender: UIButton) {
guard let passwordTextField = passwordTextField,
let verifyPasswordTextField = verifyPasswordTextField,
let text = passwordTextField.text else { return }
let item = KeychainPasswordItem(service: KeychainConfiguration.serviceName, account: "Master Password")
if text.count > 0, text == verifyPasswordTextField.text {
do {
try item.savePassword(text)
} catch {
print("Master password saving error: \(error)")
}
let title = NSLocalizedString("Password has been successfully changed", comment: "")
let message = NSLocalizedString("Tip: To use old notes, you must decrypt them separately with the old key and encrypt them again.", comment: "")
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertController.Style.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
present(alert, animated: true, completion: nil)
return
}
let title = NSLocalizedString("Please try again", comment: "")
let message = NSLocalizedString("Wrong repeated password", comment: "")
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertController.Style.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
present(alert, animated: true, completion: nil)
}
}
================================================
FILE: FSNotes iOS/Preferences/SettingsEditorViewController.swift
================================================
//
// SettingsEditorViewController.swift
// FSNotes iOS
//
// Created by Олександр Глущенко on 07.08.2020.
// Copyright © 2020 Oleksandr Glushchenko. All rights reserved.
//
import UIKit
class SettingsEditorViewController: UITableViewController {
private var noteTableUpdater = Timer()
private var sections = [
NSLocalizedString("Settings", comment: ""),
NSLocalizedString("View", comment: ""),
NSLocalizedString("Line Spacing", comment: "Settings"),
NSLocalizedString("Font", comment: ""),
NSLocalizedString("Code", comment: "")
]
private var rowsInSection = [2, 2, 1, 3, 2]
private var counter = UILabel(frame: CGRect(x: 0, y: 0, width: 20, height: 20))
private var rows = [
[
NSLocalizedString("Autocorrection", comment: "Settings"),
NSLocalizedString("Check Spelling", comment: "Settings"),
],
[
NSLocalizedString("Code Block Live Highlighting", comment: "Settings"),
NSLocalizedString("MathJax", comment: "Settings"),
],
[""],
[
NSLocalizedString("Family", comment: "Settings"),
NSLocalizedString("Dynamic Type", comment: "Settings"),
NSLocalizedString("Font Size", comment: "Settings")
],
[
NSLocalizedString("Font", comment: "Settings"),
NSLocalizedString("Theme", comment: "Settings"),
]
]
override func viewDidLoad() {
title = NSLocalizedString("Editor", comment: "Settings")
super.viewDidLoad()
}
@objc func cancel() {
self.navigationController?.popViewController(animated: true)
}
override func numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return rowsInSection[section]
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sections[section]
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 50
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.section == 3 && indexPath.row == 0 {
let controller = FontViewController()
self.navigationController?.pushViewController(controller, animated: true)
}
if indexPath.section == 4 && indexPath.row == 0 {
let controller = CodeFontViewController()
self.navigationController?.pushViewController(controller, animated: true)
}
if indexPath.section == 4 && indexPath.row == 1 {
let controller = CodeThemeViewController()
self.navigationController?.pushViewController(controller, animated: true)
}
tableView.deselectRow(at: indexPath, animated: false)
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let uiSwitch = UISwitch()
uiSwitch.addTarget(self, action: #selector(switchValueDidChange(_:)), for: .valueChanged)
let cell = UITableViewCell()
cell.textLabel?.text = rows[indexPath.section][indexPath.row]
if indexPath.section == 0 {
switch indexPath.row {
case 0:
cell.accessoryView = uiSwitch
uiSwitch.isOn = UserDefaultsManagement.editorAutocorrection
case 1:
cell.accessoryView = uiSwitch
uiSwitch.isOn = UserDefaultsManagement.editorSpellChecking
default:
return cell
}
}
if indexPath.section == 1 {
switch indexPath.row {
case 0:
cell.accessoryView = uiSwitch
uiSwitch.isOn = UserDefaultsManagement.codeBlockHighlight
case 1:
cell.accessoryView = uiSwitch
uiSwitch.isOn = UserDefaultsManagement.mathJaxPreview
default:
return cell
}
}
if indexPath.section == 2 {
let brightness = UserDefaultsManagement.editorLineSpacing
let slider = UISlider(frame: CGRect(x: 10, y: 3, width: tableView.frame.width - 20, height: 40))
slider.minimumValue = 0
slider.maximumValue = 25
slider.addTarget(self, action: #selector(didChangeLineSpacingSlider), for: .touchUpInside)
slider.setValue(brightness, animated: true)
cell.addSubview(slider)
}
if indexPath.section == 3 {
switch indexPath.row {
case 0:
cell.accessoryType = .disclosureIndicator
case 1:
cell.accessoryView = uiSwitch
uiSwitch.isOn = UserDefaultsManagement.dynamicTypeFont
case 2:
if UserDefaultsManagement.dynamicTypeFont {
cell.isHidden = true
return cell
}
let stepper = UIStepper(frame: CGRect(x: 20, y: 20, width: 100, height: 20))
stepper.stepValue = 1
stepper.minimumValue = 10
stepper.maximumValue = 40
stepper.value = Double(UserDefaultsManagement.fontSize)
stepper.translatesAutoresizingMaskIntoConstraints = false
stepper.addTarget(self, action: #selector(fontSizeChanged), for: .valueChanged)
let label = UILabel()
label.text = ""
label.translatesAutoresizingMaskIntoConstraints = false
counter.text = String(Double(UserDefaultsManagement.fontSize))
counter.textColor = UIColor.blackWhite
counter.translatesAutoresizingMaskIntoConstraints = false
cell.contentView.addSubview(label)
cell.contentView.addSubview(counter)
cell.contentView.addSubview(stepper)
cell.selectionStyle = .none
cell.accessoryType = .none
let views = ["name" : label, "counter": counter, "stepper" : stepper] as [String : Any]
cell.contentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-10-[name]-[counter(40)]-15-[stepper(100)]-20-|", options: NSLayoutConstraint.FormatOptions.alignAllCenterY, metrics: nil, views: views))
cell.contentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-10-[name(stepper)]-10-|", options: [], metrics: nil, views: views))
default:
return cell
}
}
if indexPath.section == 4 {
switch indexPath.row {
case 0:
cell.accessoryType = .disclosureIndicator
break
case 1:
cell.accessoryType = .disclosureIndicator
break
default:
break
}
}
return cell
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if (indexPath.section == 3 && indexPath.row == 2 && UserDefaultsManagement.dynamicTypeFont) {
return 0
}
return super.tableView(tableView, heightForRowAt: indexPath)
}
@objc public func switchValueDidChange(_ sender: UISwitch) {
guard let cell = sender.superview as? UITableViewCell,
let tableView = cell.superview as? UITableView,
let indexPath = tableView.indexPath(for: cell) else { return }
if indexPath.section == 0 {
switch indexPath.row {
case 0:
guard let uiSwitch = cell.accessoryView as? UISwitch else { return }
UserDefaultsManagement.editorAutocorrection = uiSwitch.isOn
UIApplication.getEVC().editArea.autocorrectionType = UserDefaultsManagement.editorAutocorrection ? .yes : .no
case 1:
guard let uiSwitch = cell.accessoryView as? UISwitch else { return }
UserDefaultsManagement.editorSpellChecking = uiSwitch.isOn
UIApplication.getEVC().editArea.spellCheckingType = UserDefaultsManagement.editorSpellChecking ? .yes : .no
default:
return
}
}
if indexPath.section == 1 {
switch indexPath.row {
case 0:
guard let uiSwitch = cell.accessoryView as? UISwitch else { return }
UserDefaultsManagement.codeBlockHighlight = uiSwitch.isOn
case 1:
guard let uiSwitch = cell.accessoryView as? UISwitch else { return }
UserDefaultsManagement.mathJaxPreview = uiSwitch.isOn
default:
return
}
}
if indexPath.section == 2 {
return
}
if indexPath.section == 3 {
switch indexPath.row {
case 0:
return
case 1:
guard let uiSwitch = cell.accessoryView as? UISwitch else { return }
UserDefaultsManagement.dynamicTypeFont = uiSwitch.isOn
if uiSwitch.isOn {
UserDefaultsManagement.fontSize = 17
}
if let dynamicCell = tableView.cellForRow(at: IndexPath(row: 2, section: 3)) {
dynamicCell.isHidden = uiSwitch.isOn
}
tableView.reloadRows(at: [IndexPath(row: 2, section: 3)], with: .automatic)
noteTableUpdater.invalidate()
noteTableUpdater = Timer.scheduledTimer(timeInterval: 1.2, target: self, selector: #selector(self.reloadNotesTable), userInfo: nil, repeats: false)
return
case 2:
return
default:
return
}
}
}
@IBAction func fontSizeChanged(stepper: UIStepper) {
UserDefaultsManagement.fontSize = Int(stepper.value)
counter.text = String(stepper.value)
noteTableUpdater.invalidate()
noteTableUpdater = Timer.scheduledTimer(timeInterval: 1.2, target: self, selector: #selector(self.reloadNotesTable), userInfo: nil, repeats: false)
}
@IBAction func reloadNotesTable() {
UIApplication.getVC().notesTable.reloadData()
}
@objc func didChangeLineSpacingSlider(sender: UISlider) {
MPreviewView.template = nil
UserDefaultsManagement.editorLineSpacing = sender.value
}
}
================================================
FILE: FSNotes iOS/Preferences/SettingsTableViewCell.swift
================================================
//
// SettingsTableViewCell.swift
// FSNotes
//
// Created by Oleksandr Hlushchenko on 15.09.2024.
// Copyright © 2024 Oleksandr Hlushchenko. All rights reserved.
//
import UIKit
class SettingsTableViewCell: UITableViewCell {
private let iconView: UIImageView = {
let imageView = UIImageView()
let symbolConfig = UIImage.SymbolConfiguration(pointSize: 18, weight: .medium)
imageView.image = UIImage(systemName: "star.fill", withConfiguration: symbolConfig)
imageView.tintColor = .white
imageView.translatesAutoresizingMaskIntoConstraints = false
return imageView
}()
private let gradientView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
private var iconName: String?
private var gradient: [String]?
init(iconName: String, gradient: [String], style: UITableViewCell.CellStyle = .subtitle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.iconName = iconName
self.gradient = gradient
let symbolConfig = UIImage.SymbolConfiguration(pointSize: 18, weight: .medium)
iconView.image = UIImage(systemName: iconName, withConfiguration: symbolConfig)
iconView.tintColor = .white
setupViews()
applyGradient()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupViews() {
contentView.addSubview(gradientView)
gradientView.addSubview(iconView)
NSLayoutConstraint.activate([
gradientView.widthAnchor.constraint(equalToConstant: 35),
gradientView.heightAnchor.constraint(equalToConstant: 35),
gradientView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
gradientView.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
iconView.centerXAnchor.constraint(equalTo: gradientView.centerXAnchor),
iconView.centerYAnchor.constraint(equalTo: gradientView.centerYAnchor),
textLabel!.leadingAnchor.constraint(equalTo: gradientView.trailingAnchor, constant: 16),
textLabel!.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -16),
])
if let detailTextLabel = detailTextLabel {
NSLayoutConstraint.activate([
textLabel!.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 10),
textLabel!.bottomAnchor.constraint(equalTo: detailTextLabel.topAnchor, constant: -4),
detailTextLabel.leadingAnchor.constraint(equalTo: textLabel!.leadingAnchor),
detailTextLabel.trailingAnchor.constraint(equalTo: textLabel!.trailingAnchor),
detailTextLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -10)
])
} else {
NSLayoutConstraint.activate([
textLabel!.centerYAnchor.constraint(equalTo: contentView.centerYAnchor)
])
}
gradientView.layer.cornerRadius = 8
gradientView.clipsToBounds = true
textLabel?.translatesAutoresizingMaskIntoConstraints = false
detailTextLabel?.translatesAutoresizingMaskIntoConstraints = false
}
private func applyGradient() {
let gradientLayer = CAGradientLayer()
let colors = [
UIColor.getBy(hex: self.gradient!.first!).cgColor,
UIColor.getBy(hex: self.gradient!.last!).cgColor
]
gradientLayer.colors = colors
gradientLayer.startPoint = CGPoint(x: 0, y: 0)
gradientLayer.endPoint = CGPoint(x: 1, y: 1)
gradientLayer.frame = CGRect(x: 0, y: 0, width: 35, height: 35)
gradientView.layer.insertSublayer(gradientLayer, at: 0)
}
}
================================================
FILE: FSNotes iOS/Preferences/SettingsViewController.swift
================================================
//
// SettingsViewController.swift
// FSNotes iOS
//
// Created by Oleksandr Glushchenko on 2/25/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import UIKit
import StoreKit
import CoreServices
import AudioToolbox
class SettingsViewController: UITableViewController, UIDocumentPickerDelegate {
var sections = [
NSLocalizedString("General", comment: "Settings"),
NSLocalizedString("Library", comment: "Settings"),
NSLocalizedString("FSNotes", comment: "Settings")
]
var rows = [
[
NSLocalizedString("Files", comment: "Settings"),
NSLocalizedString("Editor", comment: "Settings"),
NSLocalizedString("Security", comment: "Settings"),
NSLocalizedString("Git", comment: "Settings"),
NSLocalizedString("Icon", comment: "Settings"),
NSLocalizedString("Advanced", comment: "Settings"),
], [
NSLocalizedString("iCloud Drive", comment: "Settings"),
NSLocalizedString("Add External Folder", comment: "Settings"),
NSLocalizedString("Folders", comment: "Settings"),
NSLocalizedString("Import Notes", comment: "Settings")
], [
NSLocalizedString("Support", comment: "Settings"),
NSLocalizedString("Website", comment: "Settings"),
"X",
NSLocalizedString("Thanks", comment: "Settings")
]
]
var icons = [
[
"doc.badge.gearshape.fill",
"paragraphsign",
"lock.fill",
"arrow.triangle.pull",
"square.grid.3x3.middleleft.filled",
"atom"
], [
"cloud.fill",
"externaldrive.fill.badge.plus",
"folder.fill.badge.gearshape",
"square.and.arrow.down.fill"
], [
"graduationcap.fill",
"house.fill",
"x.circle.fill",
"heart.fill"
]
]
private var gradients = [
[
["#0a84ff", "#30d158"],
["#ff453a", "#ff9f0a"],
["#bf5af2", "#40c8e0"],
["#8e8e93", "#48484a"],
["#5e5ce6", "#8e8e93"],
["#dc1c13", "#f07470"]
],
[
["#009bf9", "#004D7C"],
["#614385", "#516395"],
["#EA8D8D", "#A890FE"],
["#0D7A25", "#40AD58"]
],
[
["#dfbd69", "#926f34"],
["#09203F", "#537895"],
["#868F96", "#596164"],
["#ff9966", "#ff5e62"]
]
]
var rowsInSection = [6, 4, 4]
override func viewWillAppear(_ animated: Bool) {
navigationController?.navigationBar.prefersLargeTitles = true
}
override func viewDidLoad() {
title = NSLocalizedString("Settings", comment: "Sidebar settings")
navigationItem.rightBarButtonItem = Buttons.getRateUs(target: self, selector: #selector(rateUs))
super.viewDidLoad()
let version = UILabel(frame: CGRect(x: 8, y: 30, width: tableView.frame.width, height: 60))
version.font = version.font.withSize(17).bold()
if let versionString = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String,
let build = Bundle.main.infoDictionary?["CFBundleVersion"] as? String {
version.text =
NSLocalizedString("Version", comment: "Settings")
+ " \(versionString) "
+ NSLocalizedString("build", comment: "Settings")
+ " \(build)"
}
version.textColor = UIColor.lightGray
version.textAlignment = .center
tableView.tableFooterView = version
navigationController?.navigationBar.prefersLargeTitles = true
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 3
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return rowsInSection[section]
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sections[section]
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 50
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let iconName = icons[indexPath.section][indexPath.row]
let gradient = gradients[indexPath.section][indexPath.row]
var cell = SettingsTableViewCell(iconName: iconName, gradient: gradient, style: .default, reuseIdentifier: iconName)
if indexPath.section == 0x01 && indexPath.row == 0x03 {
cell = SettingsTableViewCell(iconName: iconName, gradient: gradient, style: .subtitle, reuseIdentifier: iconName)
}
cell.textLabel?.text = rows[indexPath.section][indexPath.row]
if indexPath.section == 0x00 {
cell.accessoryType = .disclosureIndicator
return cell
}
if indexPath.section == 0x01 {
switch indexPath.row {
case 0:
let uiSwitch = UISwitch()
uiSwitch.addTarget(self, action: #selector(switchValueDidChange(_:)), for: .valueChanged)
uiSwitch.isOn = UserDefaultsManagement.iCloudDrive
cell.textLabel?.text = "iCloud Drive"
cell.accessoryView = uiSwitch
case 1:
cell.accessoryType = .none
case 2:
cell.accessoryType = .disclosureIndicator
case 3:
cell.detailTextLabel?.textColor = UIColor.blackWhite
cell.detailTextLabel?.numberOfLines = 0
cell.detailTextLabel?.lineBreakMode = .byWordWrapping
cell.detailTextLabel?.text = NSLocalizedString("Compatible with Bear and Ulysses (textbundle), markdown, txt.", comment: "")
default:
return cell
}
}
if indexPath.section == 0x02 && indexPath.row == 0x03 {
cell.accessoryType = .disclosureIndicator
return cell
}
return cell
}
private func image( _ image:UIImage, withSize newSize:CGSize) -> UIImage {
UIGraphicsBeginImageContextWithOptions(newSize, false, UIScreen.main.scale)
image.draw(in: CGRect(x: 0,y: 0,width: newSize.width,height: newSize.height))
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!.withRenderingMode(.automatic)
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
defer {
tableView.deselectRow(at: indexPath, animated: false)
}
var lvc: UIViewController?
if indexPath.section == 0x00 {
switch indexPath.row {
case 0:
lvc = DefaultExtensionViewController()
case 1:
lvc = SettingsEditorViewController()
case 2:
lvc = SecurityViewController()
case 3:
guard let project = Storage.shared().getDefault() else { return }
lvc = AppDelegate.getGitVC(for: project)
case 4:
lvc = AppIconViewController()
case 5:
lvc = ProViewController()
default:
return
}
}
if indexPath.section == 0x01 {
switch indexPath.row {
case 0:
break
case 1:
if #available(iOS 13.0, *) {
let viewController = ExternalViewController(forOpeningContentTypes: [.folder], asCopy: false)
viewController.delegate = viewController
present(viewController, animated: true, completion: nil)
}
break
case 2:
lvc = ProjectsViewController()
break
case 3:
var picker: UIDocumentPickerViewController
if #available(iOS 14.0, *) {
picker = UIDocumentPickerViewController(forOpeningContentTypes: [.item])
} else {
picker = UIDocumentPickerViewController(documentTypes: ["public.item"], in: .import)
}
picker.allowsMultipleSelection = true
picker.delegate = self
self.present(picker, animated: true, completion: nil)
break
default: break
}
}
if indexPath.section == 0x02 {
var url: URL?
switch indexPath.row {
case 0x00:
url = URL(string: "https://github.com/glushchenko/fsnotes/issues")
break
case 0x01:
url = URL(string: "https://fsnot.es")
break
case 0x02:
url = URL(string: "https://twitter.com/fsnotesapp")
break
case 0x03:
lvc = ThanksViewController()
break
default: break
}
if let url = url {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
}
if let controller = lvc {
self.navigationController?.pushViewController(controller, animated: true)
}
}
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
guard let storageUrl = UserDefaultsManagement.storageUrl else { return }
for url in urls {
try? FileManager.default.copyItem(at: url, to: storageUrl.appendingPathComponent(url.lastPathComponent))
}
}
@objc func rateUs() {
if let scene = UIApplication.shared.connectedScenes.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene {
DispatchQueue.main.async {
AudioServicesPlaySystemSound(1519)
SKStoreReviewController.requestReview(in: scene)
}
}
}
@objc func done() {
navigationController?.popViewController(animated: true)
}
@objc public func switchValueDidChange(_ sender: UISwitch) {
guard let cell = sender.superview as? UITableViewCell else { return }
guard let uiSwitch = cell.accessoryView as? UISwitch else { return }
UserDefaultsManagement.iCloudDrive = uiSwitch.isOn
UIApplication.getVC().reloadDatabase()
if !uiSwitch.isOn {
UIApplication.getVC().stopCloudDriveSyncEngine()
}
}
}
================================================
FILE: FSNotes iOS/Preferences/SidebarViewController.swift
================================================
//
// SidebarViewController.swift
// FSNotes iOS
//
// Created by Александр on 08.03.2022.
// Copyright © 2022 Oleksandr Glushchenko. All rights reserved.
//
import UIKit
class SidebarViewController: UITableViewController {
private var rows = [
NSLocalizedString("Notes", comment: ""),
NSLocalizedString("Inbox", comment: ""),
NSLocalizedString("Todo", comment: ""),
NSLocalizedString("Untagged", comment: ""),
NSLocalizedString("Trash", comment: ""),
]
override func viewDidLoad() {
self.title = NSLocalizedString("Library", comment: "Settings")
super.viewDidLoad()
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: false)
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return rows.count
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 50
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel?.text = rows[indexPath.row]
let uiSwitch = UISwitch()
uiSwitch.addTarget(self, action: #selector(switchValueDidChange(_:)), for: .valueChanged)
switch indexPath.row {
case 0:
uiSwitch.isOn = UserDefaultsManagement.sidebarVisibilityNotes
break
case 1:
uiSwitch.isOn = UserDefaultsManagement.sidebarVisibilityInbox
break
case 2:
uiSwitch.isOn = UserDefaultsManagement.sidebarVisibilityTodo
break
case 3:
uiSwitch.isOn = UserDefaultsManagement.sidebarVisibilityUntagged
break
case 4:
uiSwitch.isOn = UserDefaultsManagement.sidebarVisibilityTrash
break
default:
break
}
cell.accessoryView = uiSwitch
return cell
}
@objc func cancel() {
navigationController?.popViewController(animated: true)
}
@objc public func switchValueDidChange(_ sender: UISwitch) {
guard let cell = sender.superview as? UITableViewCell,
let tableView = cell.superview as? UITableView,
let indexPath = tableView.indexPath(for: cell) else { return }
guard let uiSwitch = cell.accessoryView as? UISwitch else { return }
switch indexPath.row {
case 0:
UserDefaultsManagement.sidebarVisibilityNotes = uiSwitch.isOn
case 1:
UserDefaultsManagement.sidebarVisibilityInbox = uiSwitch.isOn
case 2:
UserDefaultsManagement.sidebarVisibilityTodo = uiSwitch.isOn
case 3:
UserDefaultsManagement.sidebarVisibilityUntagged = uiSwitch.isOn
case 4:
UserDefaultsManagement.sidebarVisibilityTrash = uiSwitch.isOn
default:
return
}
UIApplication.getVC().sidebarTableView.reloadSidebar()
}
}
================================================
FILE: FSNotes iOS/Preferences/SortByViewController.swift
================================================
//
// SortByViewController.swift
// FSNotes iOS
//
// Created by Александр on 06.03.2022.
// Copyright © 2022 Oleksandr Glushchenko. All rights reserved.
//
import UIKit
class SortByViewController: UITableViewController {
private var rows = [
NSLocalizedString("Modification Date", comment: ""),
NSLocalizedString("Creation Date", comment: ""),
NSLocalizedString("Title", comment: "")
]
override func viewDidLoad() {
self.title = NSLocalizedString("Sort By", comment: "Settings")
super.viewDidLoad()
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let vc = UIApplication.getVC()
if let cell = tableView.cellForRow(at: indexPath) {
if indexPath.section == 0x00 {
for row in 0...rows.count {
let cell = tableView.cellForRow(at: IndexPath(row: row, section: 0))
cell?.accessoryType = .none
}
if let sort = SortBy(rawValue: cell.reuseIdentifier!) {
UserDefaultsManagement.sort = sort
vc.reloadNotesTable()
}
if cell.accessoryType == .none {
cell.accessoryType = .checkmark
} else {
cell.accessoryType = .none
}
}
}
cancel()
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return rows.count
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 50
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = UITableViewCell()
if indexPath.section == 0x00 {
switch indexPath.row {
case 0:
cell = UITableViewCell(style: .default, reuseIdentifier: "modificationDate")
cell.textLabel?.text = NSLocalizedString("Modification Date", comment: "")
if UserDefaultsManagement.sort == .modificationDate {
cell.accessoryType = .checkmark
}
break
case 1:
cell = UITableViewCell(style: .default, reuseIdentifier: "creationDate")
cell.textLabel?.text = NSLocalizedString("Creation Date", comment: "")
if UserDefaultsManagement.sort == .creationDate {
cell.accessoryType = .checkmark
}
break
case 2:
cell = UITableViewCell(style: .default, reuseIdentifier: "title")
cell.textLabel?.text = NSLocalizedString("Title", comment: "")
if UserDefaultsManagement.sort == .title {
cell.accessoryType = .checkmark
}
break
default:
break
}
}
return cell
}
@objc func cancel() {
navigationController?.popViewController(animated: true)
}
@objc func close() {
dismiss(animated: true, completion: nil)
}
}
================================================
FILE: FSNotes iOS/Preferences/ThanksViewController.swift
================================================
//
// ThanksViewController.swift
// FSNotes iOS
//
// Created by Александр on 06.03.2022.
// Copyright © 2022 Oleksandr Glushchenko. All rights reserved.
//
import UIKit
class ThanksViewController: UITableViewController {
private var rows = [
"Radio-T",
"Matt Septhon",
"Dylan Seeger (Icon design)"
]
private var urls = [
"https://radio-t.com",
"https://www.gingerbeardman.com",
"https://lovably.com"
]
override func viewDidLoad() {
self.title = NSLocalizedString("Thanks", comment: "Settings")
super.viewDidLoad()
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let url = URL(string: urls[indexPath.row]) {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
tableView.deselectRow(at: indexPath, animated: false)
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return rows.count
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 50
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel?.text = rows[indexPath.row]
return cell
}
@objc func cancel() {
navigationController?.popViewController(animated: true)
}
}
================================================
FILE: FSNotes iOS/RevisionsViewController.swift
================================================
//
// RevisionsViewController.swift
// FSNotes iOS
//
// Created by Александр on 14.02.2022.
// Copyright © 2022 Oleksandr Glushchenko. All rights reserved.
//
import Foundation
import UIKit
class RevisionsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var navItem: UINavigationItem!
@IBOutlet weak var navigationBar: UINavigationBar!
@IBOutlet weak var bottomSafeView: UIView!
@IBOutlet weak var revisionsTable: UITableView!
public var note: Note?
private var revisions = [Revision]()
override func viewDidLoad() {
super.viewDidLoad()
navigationBar.barTintColor = UIColor.sidebar
navigationBar.tintColor = UIColor.mainTheme
navigationBar.backgroundColor = UIColor.sidebar
bottomSafeView.backgroundColor = UIColor.sidebar
if let urls = note?.listRevisions() {
revisions = urls
}
revisionsTable.delegate = self
revisionsTable.dataSource = self
initButtons()
}
private func initButtons() {
var buttons = [UIBarButtonItem]()
let leftString = NSLocalizedString("Cancel", comment: "")
navItem.leftBarButtonItem = UIBarButtonItem(title: leftString, style: .plain, target: self, action: #selector(closeController))
if let project = note?.project, !project.hasRepository() {
let dropImage = UIImage(systemName: "trash")
let dropBarButton = UIBarButtonItem(image: dropImage, landscapeImagePhone: nil, style: .done, target: self, action: #selector(dropRevisions))
buttons.append(dropBarButton)
}
let saveImage = UIImage(systemName: "plus.circle")
let saveBarButton = UIBarButtonItem(image: saveImage, landscapeImagePhone: nil, style: .done, target: self, action: #selector(saveRevision))
buttons.append(saveBarButton)
navItem.rightBarButtonItems = buttons
}
@IBAction func dropRevisions() {
let title = NSLocalizedString("Сlearing history", comment: "")
let message = NSLocalizedString("Are you sure you want to delete all versions of this note?", comment: "")
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default) { (_) in
self.note?.dropRevisions()
self.dismiss(animated: true)
})
let cancel = NSLocalizedString("Cancel", comment: "")
alert.addAction(UIAlertAction(title: cancel, style: .cancel, handler: { (action: UIAlertAction!) in
}))
self.present(alert, animated: true, completion: nil)
}
@IBAction func saveRevision() {
guard let note = note else { return }
UIApplication.getVC().notesTable.saveRevisionAction(note: note)
dismiss(animated: true)
}
@IBAction func closeController() {
dismiss(animated: true)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return revisions.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
let date = Date(timeIntervalSince1970: revisions[indexPath.row].timestamp)
let dateFormatter = DateFormatter()
dateFormatter.timeStyle = DateFormatter.Style.medium //Set time style
dateFormatter.dateStyle = DateFormatter.Style.medium //Set date style
dateFormatter.timeZone = .current
let localDate = dateFormatter.string(from: date)
cell.textLabel?.text = localDate
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 70
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return NSLocalizedString("Saved versions", comment: "")
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 100
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let revision = revisions[indexPath.row]
note?.restore(revision: revision)
UIApplication.getEVC().refill()
dismiss(animated: true)
}
func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
guard let headerView = view as? UITableViewHeaderFooterView else { return }
headerView.textLabel?.font = .preferredFont(forTextStyle: .title1, compatibleWith: nil)
}
}
================================================
FILE: FSNotes iOS/SceneDelegate.swift
================================================
//
// SceneDelegate.swift
// FSNotes
//
// Created by Oleksandr Hlushchenko on 15.11.2025.
// Copyright © 2025 Oleksandr Hlushchenko. All rights reserved.
//
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
var launchedShortcutItem: UIApplicationShortcutItem?
var listController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "listViewController") as! ViewController
var editorController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "editorViewController") as! EditorViewController
var mainController: MainNavigationController?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
// Handle shortcut from cold launch
if let shortcutItem = connectionOptions.shortcutItem {
launchedShortcutItem = shortcutItem
}
window = UIWindow(windowScene: windowScene)
let nav = MainNavigationController(rootViewController: listController)
nav.setNavigationBarHidden(false, animated: false)
mainController = nav
window?.rootViewController = nav
window?.makeKeyAndVisible()
editorController.loadViewIfNeeded()
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
if let shortcutItem = self.launchedShortcutItem {
self.handle(shortcutItem: shortcutItem)
}
if let urlContext = connectionOptions.urlContexts.first {
self.handle(url: urlContext.url)
}
if let userActivity = connectionOptions.userActivities.first ?? session.stateRestorationActivity {
self.configure(window: self.window, with: userActivity)
}
}
}
func sceneDidDisconnect(_ scene: UIScene) {
// Called as the scene is being released by the system.
}
func sceneDidBecomeActive(_ scene: UIScene) {
// Called when the scene has moved from an inactive state to an active state.
}
func sceneWillResignActive(_ scene: UIScene) {
// Called when the scene will move from an active state to an inactive state.
}
func sceneWillEnterForeground(_ scene: UIScene) {
// Called as the scene transitions from the background to the foreground.
}
func sceneDidEnterBackground(_ scene: UIScene) {
// Called as the scene transitions from the foreground to the background.
saveEditorState()
}
// MARK: - Shortcut Actions
func windowScene(_ windowScene: UIWindowScene, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
handle(shortcutItem: shortcutItem)
completionHandler(true)
}
private func handle(shortcutItem: UIApplicationShortcutItem) {
if ShortcutIdentifier(fullType: shortcutItem.type) == .search {
UIApplication.getVC().enableSearchFocus()
}
UIApplication.getVC().handleShortCutItem(shortcutItem)
}
// MARK: - URL Handling
func scene(_ scene: UIScene, openURLContexts URLContexts: Set) {
guard let url = URLContexts.first?.url else { return }
handle(url: url)
}
private func handle(url: URL) {
let vc = UIApplication.getVC()
let storage = Storage.shared()
var note = storage.getBy(url: url)
if url.host == "open" {
if let tag = url["tag"]?.removingPercentEncoding {
vc.sidebarTableView.select(tag: tag)
mainController?.popToRootViewController(animated: true)
return
}
}
if url.host == "find" {
if let id = url["id"]?.removingPercentEncoding {
note = storage.getBy(title: id)
if !vc.isLoadedDB, note == nil {
vc.restoreFindID = id
return
}
}
}
if let note = note {
UIApplication.getEVC().fill(note: note)
UIApplication.getVC().openEditorViewController()
print("File imported: \(note.url)")
} else {
guard url.startAccessingSecurityScopedResource(), let inbox = storage.getDefault() else {
return
}
let dst = NameHelper.getUniqueFileName(name: "", project: inbox, ext: url.pathExtension)
do {
try FileManager.default.copyItem(at: url, to: dst)
if let note = storage.importNote(url: dst) {
vc.notesTable.insertRows(notes: [note])
vc.updateNotesCounter()
}
} catch {
print("Note opening error: \(error)")
}
}
}
// MARK: - State Restoration
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
configure(window: window, with: userActivity)
}
func configure(window: UIWindow?, with activity: NSUserActivity) {
UIApplication.getEVC().restoreUserActivityState(activity)
}
func stateRestorationActivity(for scene: UIScene) -> NSUserActivity? {
return scene.userActivity
}
// MARK: - Helper Methods
private func saveEditorState() {
let evc = UIApplication.getEVC()
guard evc.navigationController?.topViewController === evc else { return }
if let url = evc.note?.url {
UserDefaultsManagement.currentEditorState = evc.editArea.isFirstResponder
if evc.note?.previewState == true {
UserDefaultsManagement.currentRange = nil
} else {
UserDefaultsManagement.currentRange = evc.editArea.selectedRange
}
UserDefaultsManagement.currentNote = url
}
}
}
================================================
FILE: FSNotes iOS/View/EditTextView.swift
================================================
//
// EditTextView.swift
// FSNotes iOS
//
// Created by Oleksandr Glushchenko on 1/29/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import UIKit
import MobileCoreServices
import UniformTypeIdentifiers
class EditTextView: UITextView, UITextViewDelegate {
public var textStorageProcessor: TextStorageProcessor?
public var isNoteLoading = false
public var isAllowedScrollRect: Bool?
public var typingFont: UIFont?
public var note: Note?
public var lasTouchPoint: CGPoint?
public var imagesLoaderQueue = OperationQueue.init()
public var keyboardIsOpened = true
public var callCounter = 0
public var isUpdating = false
required init?(coder: NSCoder) {
if #available(iOS 13.2, *) {
super.init(coder: coder)
}
else {
super.init(frame: .zero, textContainer: nil)
self.autoresizingMask = [.flexibleWidth, .flexibleHeight]
self.contentMode = .scaleToFill
self.isScrollEnabled = false // causes expanding height
// Auto Layout
self.translatesAutoresizingMaskIntoConstraints = false
self.font = UIFont(name: "HelveticaNeue", size: 18)
}
autocorrectionType = UserDefaultsManagement.editorAutocorrection ? .yes : .no
spellCheckingType = UserDefaultsManagement.editorSpellChecking ? .yes : .no
}
override func becomeFirstResponder() -> Bool {
textStorage.removeHighlight()
return super.becomeFirstResponder()
}
override func touchesEnded(_ touches: Set, with event: UIEvent?) {
super.touchesEnded(touches, with: event)
if !isFirstResponder && window != nil {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in
guard let self = self else { return }
if !self.isFirstResponder && self.window != nil {
_ = self.becomeFirstResponder()
}
}
}
}
public func initTextStorage() {
let processor = TextStorageProcessor()
processor.editor = self
textStorageProcessor = processor
textStorage.delegate = processor
}
override func selectionRects(for range: UITextRange) -> [UITextSelectionRect] {
let selectionRects = super.selectionRects(for: range)
let fontHeight = UserDefaultsManagement.noteFont.lineHeight
let lineSpacing = CGFloat(UserDefaultsManagement.editorLineSpacing)
let endCharacterIndex = offset(from: beginningOfDocument, to: range.end)
let endParRange = textStorage.mutableString.paragraphRange(for: NSRange(location: endCharacterIndex, length: 0))
var lastWideRect: UITextSelectionRect?
if selectionRects.count > 2 {
lastWideRect = selectionRects[selectionRects.count - 3]
}
var result = [UITextSelectionRect]()
for selectionRect in selectionRects {
if selectionRect.rect.width == 0 {
let customRect = CGRect(x: selectionRect.rect.origin.x, y: selectionRect.rect.origin.y - lineSpacing / 2, width: 0, height: fontHeight + lineSpacing)
let sel = EditorSelectionRect(originalRect: selectionRect, rect: customRect)
result.append(sel)
} else {
var heightOffset = CGFloat(0)
if endParRange.upperBound == textStorage.length && lastWideRect == selectionRect {
heightOffset += lineSpacing
}
let customRect = CGRect(x: selectionRect.rect.origin.x, y: selectionRect.rect.origin.y - lineSpacing / 2, width: selectionRect.rect.width, height: selectionRect.rect.height + heightOffset)
let selectionRect = EditorSelectionRect(originalRect: selectionRect, rect: customRect)
result.append(selectionRect)
}
}
return result
}
override func caretRect(for position: UITextPosition) -> CGRect {
let characterIndex = offset(from: beginningOfDocument, to: position)
guard layoutManager.isValidGlyphIndex(characterIndex) else {
return super.caretRect(for: position)
}
let glyphIndex = layoutManager.glyphIndexForCharacter(at: characterIndex)
let usedLineFragment = layoutManager.lineFragmentUsedRect(forGlyphAt: glyphIndex, effectiveRange: nil)
guard !usedLineFragment.isEmpty else {
return super.caretRect(for: position)
}
var caretRect = super.caretRect(for: position)
caretRect.origin.y = usedLineFragment.origin.y + textContainerInset.top
caretRect.size.height = usedLineFragment.size.height - CGFloat(UserDefaultsManagement.editorLineSpacing) / 2
return caretRect
}
override func scrollRectToVisible(_ rect: CGRect, animated: Bool) {
guard isAllowedScrollRect == true else { return }
callCounter += 1
if keyboardIsOpened {
DispatchQueue.main.async {
UIView.animate(withDuration: 0.8, delay: 0, options: .beginFromCurrentState, animations: {
super.scrollRectToVisible(rect, animated: false)
})
}
if callCounter > 2 {
keyboardIsOpened = false
callCounter = 0
}
} else {
super.scrollRectToVisible(rect, animated: animated)
}
}
override func cut(_ sender: Any?) {
let range = selectedRange
guard range.length > 0 else { return }
let selectedString = textStorage.attributedSubstring(from: range)
let attributedString = NSMutableAttributedString(attributedString: selectedString)
.unloadTasks()
attributedString.saveData()
super.cut(sender)
do {
let data = try NSKeyedArchiver.archivedData(
withRootObject: attributedString,
requiringSecureCoding: false
)
UIPasteboard.general.setItems([
[
UIPasteboard.attributed: data,
UTType.plainText.identifier: attributedString.string
]
])
} catch {
print("Serialization error: \(error)")
}
}
override func paste(_ sender: Any?) {
isUpdating = true
defer {
DispatchQueue.main.async {
self.isUpdating = false
}
}
let pb = UIPasteboard.general
var toInsert: NSAttributedString?
if let imageData = pb.data(forPasteboardType: UTType.png.identifier) ??
pb.data(forPasteboardType: UTType.jpeg.identifier) ??
pb.data(forPasteboardType: UTType.image.identifier) {
toInsert = NSMutableAttributedString.build(data: imageData)
}
else if let data = pb.data(forPasteboardType: UIPasteboard.attributed) {
do {
if let attributed = try NSKeyedUnarchiver.unarchivedObject(
ofClass: NSAttributedString.self,
from: data
) {
let mutable = NSMutableAttributedString(attributedString: attributed)
mutable.loadTasks()
toInsert = mutable
}
} catch {
print("Paste error: \(error)")
}
}
else if let plain = pb.string {
let mutable = NSMutableAttributedString(string: plain)
mutable.loadTasks()
mutable.loadFont()
toInsert = mutable
}
guard let attrToInsert = toInsert else {
super.paste(sender)
return
}
let range = self.selectedRange
if let should = delegate?.textView?(self, shouldChangeTextIn: range, replacementText: attrToInsert.string), !should {
return
}
self.insertAttributedText(attrToInsert)
}
override func copy(_ sender: Any?) {
guard selectedRange.length > 0 else { return }
let selectedString = textStorage.attributedSubstring(from: self.selectedRange)
let attributedString = NSMutableAttributedString(attributedString: selectedString).unloadTasks()
attributedString.saveData()
do {
let data = try NSKeyedArchiver.archivedData(
withRootObject: attributedString,
requiringSecureCoding: false
)
UIPasteboard.general.setItems([
[
UIPasteboard.attributed: data,
UTType.plainText.identifier: attributedString.string
]
])
return
} catch {
print("Serialization error: \(error)")
}
super.copy(sender)
}
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
if action == #selector(UIResponderStandardEditActions.paste(_:)) {
return true
}
return super.canPerformAction(action, withSender: sender)
}
public func initUndoRedoButons() {
UIApplication.getEVC().undoBarButton?.isEnabled = undoManager?.canUndo == true
UIApplication.getEVC().redoBarButton?.isEnabled = undoManager?.canRedo == true
}
public func isTodo(at location: Int) -> Bool {
let storage = self.textStorage
if storage.length > location, storage.attribute(.todo, at: location, effectiveRange: nil) != nil {
return true
}
let range = (storage.string as NSString).paragraphRange(for: NSRange(location: location, length: 0))
let string = storage.attributedSubstring(from: range).string as NSString
var length = string.range(of: "- [ ]").length
if length == 0 {
length = string.range(of: "- [x]").length
}
if length > 0 {
let upper = range.location + length
if location >= range.location && location <= upper {
return true
}
}
return false
}
public func isImage(at location: Int) -> Bool {
return textStorage.getMeta(at: location) != nil
}
public func isLink(at location: Int) -> Bool {
let storage = self.textStorage
if storage.length > location, storage.attribute(.link, at: location, effectiveRange: nil) != nil {
return true
}
return false
}
public func isWikiLink(at location: Int) -> Bool {
let storage = self.textStorage
if storage.length > location, let path = storage.attribute(.link, at: location, effectiveRange: nil) as? String, path.starts(with: "fsnotes://find?id=") {
return true
}
return false
}
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
UIApplication.getEVC().themeObserver()
}
}
struct Undo {
var range: NSRange
var string: NSAttributedString
}
================================================
FILE: FSNotes iOS/View/EditorSelectionRect.swift
================================================
//
// EditorSelectionRect.swift
// FSNotes iOS
//
// Created by Александр on 11.02.2022.
// Copyright © 2022 Oleksandr Glushchenko. All rights reserved.
//
import UIKit
class EditorSelectionRect: UITextSelectionRect {
private let original: UITextSelectionRect
private var customRect: CGRect? = nil
override var rect: CGRect {
if let customRect = customRect {
return customRect
}
return original.rect
}
override var writingDirection: NSWritingDirection {
return original.writingDirection
}
override var containsStart: Bool {
return original.containsStart
}
override var containsEnd: Bool {
return original.containsEnd
}
override var isVertical: Bool {
return original.isVertical
}
init(originalRect original: UITextSelectionRect, rect: CGRect) {
self.original = original
self.customRect = rect
}
}
================================================
FILE: FSNotes iOS/View/ImageScrollView.swift
================================================
//
// ImageScrollView.swift
// Beauty
//
// Created by Nguyen Cong Huy on 1/19/16.
// Copyright © 2016 Nguyen Cong Huy. All rights reserved.
//
import UIKit
@objc public protocol ImageScrollViewDelegate: UIScrollViewDelegate {
func imageScrollViewDidChangeOrientation(imageScrollView: ImageScrollView)
}
open class ImageScrollView: UIScrollView {
@objc public enum ScaleMode: Int {
case aspectFill
case aspectFit
case widthFill
case heightFill
}
@objc public enum Offset: Int {
case begining
case center
}
static let kZoomInFactorFromMinWhenDoubleTap: CGFloat = 2
@objc open var imageContentMode: ScaleMode = .widthFill
@objc open var initialOffset: Offset = .begining
@objc public private(set) var zoomView: UIImageView? = nil
@objc open weak var imageScrollViewDelegate: ImageScrollViewDelegate?
var imageSize: CGSize = CGSize.zero
private var pointToCenterAfterResize: CGPoint = CGPoint.zero
private var scaleToRestoreAfterResize: CGFloat = 1.0
open var maxScaleFromMinScale: CGFloat = 3.0
override open var frame: CGRect {
willSet {
if frame.equalTo(newValue) == false && newValue.equalTo(CGRect.zero) == false && imageSize.equalTo(CGSize.zero) == false {
prepareToResize()
}
}
didSet {
if frame.equalTo(oldValue) == false && frame.equalTo(CGRect.zero) == false && imageSize.equalTo(CGSize.zero) == false {
recoverFromResizing()
}
}
}
override public init(frame: CGRect) {
super.init(frame: frame)
initialize()
}
required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
initialize()
}
deinit {
NotificationCenter.default.removeObserver(self)
}
private func initialize() {
showsVerticalScrollIndicator = false
showsHorizontalScrollIndicator = false
bouncesZoom = true
decelerationRate = UIScrollView.DecelerationRate.fast
delegate = self
NotificationCenter.default.addObserver(self, selector: #selector(ImageScrollView.changeOrientationNotification), name: UIDevice.orientationDidChangeNotification, object: nil)
}
@objc public func adjustFrameToCenter() {
guard let unwrappedZoomView = zoomView else {
return
}
var frameToCenter = unwrappedZoomView.frame
// center horizontally
if frameToCenter.size.width < bounds.width {
frameToCenter.origin.x = (bounds.width - frameToCenter.size.width) / 2
}
else {
frameToCenter.origin.x = 0
}
// center vertically
if frameToCenter.size.height < bounds.height {
frameToCenter.origin.y = (bounds.height - frameToCenter.size.height) / 2
}
else {
frameToCenter.origin.y = 0
}
unwrappedZoomView.frame = frameToCenter
}
private func prepareToResize() {
let boundsCenter = CGPoint(x: bounds.midX, y: bounds.midY)
pointToCenterAfterResize = convert(boundsCenter, to: zoomView)
scaleToRestoreAfterResize = zoomScale
// If we're at the minimum zoom scale, preserve that by returning 0, which will be converted to the minimum
// allowable scale when the scale is restored.
if scaleToRestoreAfterResize <= minimumZoomScale + CGFloat(Float.ulpOfOne) {
scaleToRestoreAfterResize = 0
}
}
private func recoverFromResizing() {
setMaxMinZoomScalesForCurrentBounds()
// restore zoom scale, first making sure it is within the allowable range.
let maxZoomScale = max(minimumZoomScale, scaleToRestoreAfterResize)
zoomScale = min(maximumZoomScale, maxZoomScale)
// restore center point, first making sure it is within the allowable range.
// convert our desired center point back to our own coordinate space
let boundsCenter = convert(pointToCenterAfterResize, to: zoomView)
// calculate the content offset that would yield that center point
var offset = CGPoint(x: boundsCenter.x - bounds.size.width/2.0, y: boundsCenter.y - bounds.size.height/2.0)
// restore offset, adjusted to be within the allowable range
let maxOffset = maximumContentOffset()
let minOffset = minimumContentOffset()
var realMaxOffset = min(maxOffset.x, offset.x)
offset.x = max(minOffset.x, realMaxOffset)
realMaxOffset = min(maxOffset.y, offset.y)
offset.y = max(minOffset.y, realMaxOffset)
contentOffset = offset
}
private func maximumContentOffset() -> CGPoint {
return CGPoint(x: contentSize.width - bounds.width,y:contentSize.height - bounds.height)
}
private func minimumContentOffset() -> CGPoint {
return CGPoint.zero
}
// MARK: - Set up
open func setup() {
var topSupperView = superview
while topSupperView?.superview != nil {
topSupperView = topSupperView?.superview
}
// Make sure views have already layout with precise frame
topSupperView?.layoutIfNeeded()
DispatchQueue.main.async {
self.refresh()
}
}
// MARK: - Display image
@objc open func display(image: UIImage) {
if let zoomView = zoomView {
zoomView.removeFromSuperview()
}
zoomView = UIImageView(image: image)
zoomView!.isUserInteractionEnabled = true
addSubview(zoomView!)
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(ImageScrollView.doubleTapGestureRecognizer(_:)))
tapGesture.numberOfTapsRequired = 2
zoomView!.addGestureRecognizer(tapGesture)
configureImageForSize(image.size)
}
private func configureImageForSize(_ size: CGSize) {
imageSize = size
contentSize = imageSize
setMaxMinZoomScalesForCurrentBounds()
zoomScale = minimumZoomScale
switch initialOffset {
case .begining:
contentOffset = CGPoint.zero
case .center:
let xOffset = contentSize.width < bounds.width ? 0 : (contentSize.width - bounds.width)/2
let yOffset = contentSize.height < bounds.height ? 0 : (contentSize.height - bounds.height)/2
switch imageContentMode {
case .aspectFit:
contentOffset = CGPoint.zero
case .aspectFill:
contentOffset = CGPoint(x: xOffset, y: yOffset)
case .heightFill:
contentOffset = CGPoint(x: xOffset, y: 0)
case .widthFill:
contentOffset = CGPoint(x: 0, y: yOffset)
}
}
}
private func setMaxMinZoomScalesForCurrentBounds() {
// calculate min/max zoomscale
let xScale = bounds.width / imageSize.width // the scale needed to perfectly fit the image width-wise
let yScale = bounds.height / imageSize.height // the scale needed to perfectly fit the image height-wise
var minScale: CGFloat = 1
switch imageContentMode {
case .aspectFill:
minScale = max(xScale, yScale)
case .aspectFit:
minScale = min(xScale, yScale)
case .widthFill:
minScale = xScale
case .heightFill:
minScale = yScale
}
let maxScale = maxScaleFromMinScale*minScale
// don't let minScale exceed maxScale. (If the image is smaller than the screen, we don't want to force it to be zoomed.)
if minScale > maxScale {
minScale = maxScale
}
maximumZoomScale = maxScale
minimumZoomScale = minScale * 0.999 // the multiply factor to prevent user cannot scroll page while they use this control in UIPageViewController
}
// MARK: - Gesture
@objc func doubleTapGestureRecognizer(_ gestureRecognizer: UIGestureRecognizer) {
// zoom out if it bigger than the scale factor after double-tap scaling. Else, zoom in
if zoomScale >= minimumZoomScale * ImageScrollView.kZoomInFactorFromMinWhenDoubleTap - 0.01 {
setZoomScale(minimumZoomScale, animated: true)
} else {
let center = gestureRecognizer.location(in: gestureRecognizer.view)
let zoomRect = zoomRectForScale(ImageScrollView.kZoomInFactorFromMinWhenDoubleTap * minimumZoomScale, center: center)
zoom(to: zoomRect, animated: true)
}
}
private func zoomRectForScale(_ scale: CGFloat, center: CGPoint) -> CGRect {
var zoomRect = CGRect.zero
// the zoom rect is in the content view's coordinates.
// at a zoom scale of 1.0, it would be the size of the imageScrollView's bounds.
// as the zoom scale decreases, so more content is visible, the size of the rect grows.
zoomRect.size.height = frame.size.height / scale
zoomRect.size.width = frame.size.width / scale
// choose an origin so as to get the right center.
zoomRect.origin.x = center.x - (zoomRect.size.width / 2.0)
zoomRect.origin.y = center.y - (zoomRect.size.height / 2.0)
return zoomRect
}
open func refresh() {
if let image = zoomView?.image {
display(image: image)
}
}
// MARK: - Actions
@objc func changeOrientationNotification() {
// A weird bug that frames are not update right after orientation changed. Need delay a little bit with async.
DispatchQueue.main.async {
self.configureImageForSize(self.imageSize)
self.imageScrollViewDelegate?.imageScrollViewDidChangeOrientation(imageScrollView: self)
}
}
}
extension ImageScrollView: UIScrollViewDelegate {
public func scrollViewDidScroll(_ scrollView: UIScrollView) {
imageScrollViewDelegate?.scrollViewDidScroll?(scrollView)
}
public func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
imageScrollViewDelegate?.scrollViewWillBeginDragging?(scrollView)
}
public func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer) {
imageScrollViewDelegate?.scrollViewWillEndDragging?(scrollView, withVelocity: velocity, targetContentOffset: targetContentOffset)
}
public func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
imageScrollViewDelegate?.scrollViewDidEndDragging?(scrollView, willDecelerate: decelerate)
}
public func scrollViewWillBeginDecelerating(_ scrollView: UIScrollView) {
imageScrollViewDelegate?.scrollViewWillBeginDecelerating?(scrollView)
}
public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
imageScrollViewDelegate?.scrollViewDidEndDecelerating?(scrollView)
}
public func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
imageScrollViewDelegate?.scrollViewDidEndScrollingAnimation?(scrollView)
}
public func scrollViewWillBeginZooming(_ scrollView: UIScrollView, with view: UIView?) {
imageScrollViewDelegate?.scrollViewWillBeginZooming?(scrollView, with: view)
}
public func scrollViewDidEndZooming(_ scrollView: UIScrollView, with view: UIView?, atScale scale: CGFloat) {
imageScrollViewDelegate?.scrollViewDidEndZooming?(scrollView, with: view, atScale: scale)
}
public func scrollViewShouldScrollToTop(_ scrollView: UIScrollView) -> Bool {
return false
}
@available(iOS 11.0, *)
public func scrollViewDidChangeAdjustedContentInset(_ scrollView: UIScrollView) {
imageScrollViewDelegate?.scrollViewDidChangeAdjustedContentInset?(scrollView)
}
public func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return zoomView
}
public func scrollViewDidZoom(_ scrollView: UIScrollView) {
adjustFrameToCenter()
imageScrollViewDelegate?.scrollViewDidZoom?(scrollView)
}
}
================================================
FILE: FSNotes iOS/View/NoteCellView.swift
================================================
//
// NoteCellView.swift
// FSNotes iOS
//
// Created by Oleksandr Glushchenko on 1/29/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import UIKit
import SwipeCellKit
class NoteCellView: SwipeTableViewCell {
@IBOutlet weak var title: UILabel!
@IBOutlet weak var date: UILabel!
@IBOutlet weak var preview: UILabel!
@IBOutlet weak var pin: UIImageView!
@IBOutlet weak var imagePreview: UIImageView!
@IBOutlet weak var imagePreviewSecond: UIImageView!
@IBOutlet weak var imagePreviewThird: UIImageView!
public var note: Note?
public var contentLength: Int = 0
public var timestamp: Int64?
public var imageKeys = [String]()
public var tableView: NotesTableView? {
get {
return self.superview as? NotesTableView
}
}
override func prepareForReuse() {
super.prepareForReuse()
imagePreview.image = nil
imagePreviewSecond.image = nil
imagePreviewThird.image = nil
imagePreview.isHidden = true
imagePreviewSecond.isHidden = true
imagePreviewThird.isHidden = true
contentLength = 0
timestamp = nil
note = nil
}
public func reLoad() {
if let note = self.note {
configure(note: note)
}
}
func configure(note: Note) {
self.note = note
date.attributedText = NSAttributedString(string: getDate())
preview.textColor = UIColor.previewColor
if note.isPublished() {
pin.image = UIImage(systemName: "globe")
pin.isHidden = false
} else if note.isEncrypted() {
let name = note.isUnlocked() ? "lock.open" : "lock"
pin.contentMode = .scaleAspectFit
pin.image = UIImage(systemName: name)
pin.isHidden = false
} else {
pin.image = UIImage(systemName: "pin")
pin.isHidden = !note.isPinned
}
pin.tintColor = UIColor.mainTheme
let font = UIFont.systemFont(ofSize: CGFloat(UserDefaultsManagement.DefaultFontSize), weight: .semibold)
let fontMetrics = UIFontMetrics(forTextStyle: .title1)
let scaledFont = fontMetrics.scaledFont(for: font)
title.font = scaledFont
let dateFont = UIFont.systemFont(ofSize: CGFloat(UserDefaultsManagement.DefaultFontSize - 2), weight: .regular)
let dateFontMetrics = UIFontMetrics(forTextStyle: .title3)
let dateScaledFont = dateFontMetrics.scaledFont(for: dateFont)
date.font = dateScaledFont
let previewFont = UIFont.systemFont(ofSize: CGFloat(UserDefaultsManagement.DefaultFontSize - 2), weight: .regular)
let previewFontMetrics = UIFontMetrics(forTextStyle: .title3)
let previewScaledFont = previewFontMetrics.scaledFont(for: previewFont)
preview.font = previewScaledFont
}
public func getDate() -> String {
if let sort = note?.project.settings.sortBy,
sort == .creationDate,
let date = note?.getCreationDateForLabel()
{
return date
}
if let date = note?.getDateForLabel() {
return date
}
return String()
}
public func reloadDate() {
date.text = getDate()
}
public func updateView() {
loadImagesPreview()
if let note = self.note {
attachHeaders(note: note)
}
reloadDate()
}
public func styleImageView(imageView: ImageView) {
imageView.isHidden = false
imageView.layer.borderWidth = 1
imageView.layer.borderColor = Color.darkGray.cgColor
imageView.layer.cornerRadius = 4
imageView.clipsToBounds = true
}
public func attachHeaders(note: Note) {
if let title = note.getTitle() {
self.title.text = title
self.preview.text = note.preview
} else {
self.title.text = String()
self.preview.text = String()
}
}
public func getPreviewImage(imageUrl: URL, note: Note) -> Image? {
let tempURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("MainNotesList")
if !FileManager.default.fileExists(atPath: tempURL.path) {
try? FileManager.default.createDirectory(at: tempURL, withIntermediateDirectories: false, attributes: nil)
}
if let cacheName = imageUrl.absoluteString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)?.md5 {
let file = tempURL.appendingPathComponent(cacheName)
if FileManager.default.fileExists(atPath: file.path) {
if let data = try? Data(contentsOf: file), let image = UIImage(data: data) {
return image
}
}
do {
let data = try Data(contentsOf: imageUrl)
if let image = UIImage(data: data) {
let size = CGRect(x: 0, y: 0, width: 70, height: 70)
if let resized = image.resize(height: 70)?.croppedInRect(rect: size) {
let jpegImageData = resized.jpegData(compressionQuality: 1)
try? jpegImageData?.write(to: file, options: .atomic)
return resized
}
}
} catch {
print(error.localizedDescription)
}
}
return nil
}
public func fixTopConstraint(position: Int?, note: Note) {
for constraint in self.contentView.constraints {
if ["firstImageTop", "secondImageTop", "thirdImageTop"].contains(constraint.identifier) {
let ident = constraint.identifier
self.contentView.removeConstraint(constraint)
let isPreviewExist = note.preview.trim().count > 0
var imageLink: UIImageView?
switch constraint.identifier {
case "firstImageTop":
imageLink = self.imagePreview
case "secondImageTop":
imageLink = self.imagePreviewSecond
case "thirdImageTop":
imageLink = self.imagePreviewThird
default:
imageLink = self.imagePreview
}
guard let firstItem = imageLink else { continue }
let secondItem = isPreviewExist ? self.preview : self.title
let constr = NSLayoutConstraint(item: firstItem, attribute: .top, relatedBy: .equal, toItem: secondItem, attribute: .bottom, multiplier: 1, constant: 12)
constr.identifier = ident
self.contentView.addConstraint(constr)
}
}
}
}
================================================
FILE: FSNotes iOS/View/NotesTableView.swift
================================================
//
// NotesTableView.swift
// FSNotes iOS
//
// Created by Oleksandr Glushchenko on 1/29/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import UIKit
import MobileCoreServices
import AudioToolbox
import SwipeCellKit
import SSZipArchive
class NotesTableView: UITableView,
UITableViewDelegate,
UITableViewDataSource,
UITableViewDragDelegate {
var notes = [Note]()
var viewDelegate: ViewController? = nil
public var selectedIndexPaths: [IndexPath]?
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return notes.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return calcHeight(indexPath: indexPath)
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return calcHeight(indexPath: indexPath)
}
func tableView(_ tableView: UITableView, contextMenuConfigurationForRowAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? {
return UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { suggestedActions in
let note = self.notes[indexPath.row]
let menu = self.makeBulkMenu(editor: false, note: note)
return menu
}
}
func tableView(_ tableView: UITableView, shouldBeginMultipleSelectionInteractionAt indexPath: IndexPath) -> Bool {
return true
}
private func calcHeight(indexPath: IndexPath) -> CGFloat {
if notes.indices.contains(indexPath.row) {
let note = notes[indexPath.row]
if let urls = note.imageUrl, urls.count > 0 {
if note.preview.count == 0 {
if note.getTitle() != nil {
// Title + image
return 132
}
// Images only
return 120
}
// Title + Prevew + Images
return 160
}
}
return 75
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "noteCell", for: indexPath) as! NoteCellView
cell.imageKeys = []
guard self.notes.indices.contains(indexPath.row) else { return cell }
let note = self.notes[indexPath.row]
if !note.isLoaded && !note.isLoadedFromCache {
note.uiLoad()
}
cell.configure(note: note)
cell.selectionStyle = .gray
cell.loadImagesPreview(position: indexPath.row)
cell.attachHeaders(note: note)
return cell
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
self.selectedIndexPaths = self.indexPathsForSelectedRows
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if isEditing {
self.selectedIndexPaths = self.indexPathsForSelectedRows
}
guard !self.isEditing, notes.indices.contains(indexPath.row) else { return }
var note = notes[indexPath.row]
note.loadPreviewState()
let evc = UIApplication.getEVC()
if let editArea = evc.editArea, let u = editArea.undoManager {
u.removeAllActions()
}
if note.container == .encryptedTextPack {
viewDelegate?.unLock(notes: [note], completion: { notes in
DispatchQueue.main.async {
guard note.container != .encryptedTextPack else {
self.askPasswordAndUnlock(note: note, indexPath: indexPath)
return
}
self.reloadRows(notes: [note])
self.fill(note: note, indexPath: indexPath)
}
})
return
}
fill(note: note, indexPath: indexPath)
if UserDefaultsManagement.autoVersioning && !note.hasGitRepository() {
DispatchQueue.global().async {
do {
try note.saveRevision()
} catch {/*_*/}
}
}
}
private func askPasswordAndUnlock(note: Note, indexPath: IndexPath) {
self.viewDelegate?.unlockPasswordPrompt(completion: { password in
self.viewDelegate?.unLock(notes: [note], completion: { success in
if let success = success, success.count > 0 {
self.reloadRows(notes: [note])
self.fill(note: note, indexPath: indexPath)
}
}, password: password)
})
}
private func askPasswordAndUnEncrypt(note: Note) {
self.viewDelegate?.unlockPasswordPrompt(completion: { password in
if note.container == .encryptedTextPack {
let success = note.unEncrypt(password: password)
note.password = nil
if success {
DispatchQueue.main.async {
UIApplication.getEVC().refill()
self.reloadRows(notes: [note], resetKeys: true)
}
}
}
})
}
private func fill(note: Note, indexPath: IndexPath) {
UIApplication.getVC().openEditorViewController()
UIApplication.getEVC().fill(note: note, clearPreview: true) {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
self.deselectRow(at: indexPath, animated: true)
}
}
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
guard let vc = viewDelegate,
!UserDefaultsManagement.sidebarIsOpened
else { return nil }
let note = self.notes[indexPath.row]
// Delete
let deleteAction = UIContextualAction(style: .destructive, title: NSLocalizedString("Delete", comment: "Table row action")) { [weak self] _, _, completion in
guard let self = self else { return }
self.viewDelegate?.sidebarTableView.removeTags(in: [note])
let isTrashed = note.isTrash()
note.remove()
self.removeRows(notes: [note])
if note.isEmpty() || isTrashed {
vc.storage.removeBy(note: note)
}
completion(true)
}
deleteAction.image = UIImage(systemName: "trash")
// Pin / Unpin
let pinTitle = note.isPinned
? NSLocalizedString("Unpin", comment: "Table row action")
: NSLocalizedString("Pin", comment: "Table row action")
let pinAction = UIContextualAction(style: .normal, title: pinTitle) { [weak self] _, _, completion in
guard let self = self,
let cell = self.cellForRow(at: indexPath) as? NoteCellView else {
completion(false)
return
}
note.togglePin()
cell.configure(note: note)
let resorted = vc.storage.sortNotes(noteList: self.notes)
guard let newIndex = resorted.firstIndex(of: note) else {
completion(false)
return
}
let newIndexPath = IndexPath(row: newIndex, section: 0)
self.moveRow(at: indexPath, to: newIndexPath)
self.notes = resorted
self.reloadRows(at: [newIndexPath], with: .automatic)
self.reloadRows(at: [indexPath], with: .automatic)
completion(true)
}
pinAction.image = note.isPinned ? UIImage(systemName: "pin.slash") : UIImage(systemName: "pin")
pinAction.backgroundColor = UIColor(red: 0.24, green: 0.59, blue: 0.94, alpha: 1.0)
let config = UISwipeActionsConfiguration(actions: [deleteAction, pinAction])
config.performsFirstActionWithFullSwipe = true
return config
}
public func turnOffEditing() {
if self.isEditing {
self.allowsMultipleSelectionDuringEditing = false
self.setEditing(false, animated: true)
deselectAllRows()
}
}
public func getSelectedNotes() -> [Note] {
var notes = [Note]()
if let selectedRows = selectedIndexPaths {
for indexPath in selectedRows {
if self.notes.indices.contains(indexPath.row) {
let note = self.notes[indexPath.row]
notes.append(note)
}
}
selectedIndexPaths = nil
}
return notes
}
public func deselectAllRows() {
if let selected = indexPathsForSelectedRows {
for indexP in selected {
deselectRow(at: indexP, animated: false)
}
}
}
public func makeBulkMenu(editor: Bool = false, note: Note) -> UIMenu? {
let handler: (_ action: UIAction) -> () = { action in
switch action.identifier.rawValue {
case "cancel":
break
case "delete":
self.removeAction(notes: [note])
if editor {
UIApplication.getEVC().cancel()
}
case "calendar":
self.dateAction(notes: [note])
case "duplicate":
self.duplicateAction(notes: [note])
case "move":
self.moveAction(notes: [note])
case "commit":
self.saveRevisionAction(note: note)
case "history":
self.historyAction(note: note)
case "rename":
self.renameAction(note: note)
case "pinUnpin":
if note.isPinned {
note.removePin()
self.removePins(notes: [note])
} else {
note.addPin()
self.addPins(notes: [note])
}
case "lockUnlock":
self.viewDelegate?.toggleNotesLock(notes: [note])
if editor {
if !note.isUnlocked() {
UIApplication.getEVC().cancel()
}
}
case "removeEncryption":
self.removeEncryption(note: note)
case "copy":
self.copyAction(note: note)
case "share":
self.shareAction(note: note)
case "shareWeb":
self.shareWebAction(note: note)
case "deleteWeb":
self.deleteWebAction(note: note)
default:
break
}
if ["pinUnpin", "removeEncryption"].contains(action.identifier.rawValue) {
DispatchQueue.main.async {
UIApplication.getEVC().configureNavMenu()
}
}
self.turnOffEditing()
}
var actions = [UIAction]()
let deleteTitle = NSLocalizedString("Delete", comment: "")
actions.append(UIAction(title: deleteTitle, image: UIImage(systemName: "trash"), identifier: UIAction.Identifier("delete"), attributes: .destructive, handler: handler))
let calendarTitle = NSLocalizedString("Change Creation Date", comment: "")
let calendarImage = UIImage(systemName: "calendar")
actions.append(UIAction(title: calendarTitle, image: calendarImage, identifier: UIAction.Identifier("calendar"), handler: handler))
let duplicateTitle = NSLocalizedString("Duplicate", comment: "")
let duplicateImage = UIImage(systemName: "doc.on.doc")
actions.append(UIAction(title: duplicateTitle, image: duplicateImage, identifier: UIAction.Identifier("duplicate"), handler: handler))
let moveTitle = NSLocalizedString("Move", comment: "")
let moveImage = UIImage(systemName: "folder")
actions.append(UIAction(title: moveTitle, image: moveImage, identifier: UIAction.Identifier("move"), handler: handler))
if note.hasGitRepository() && !note.isEncrypted() {
let commitTitle = NSLocalizedString("Save Revision", comment: "")
let commitImage = UIImage(systemName: "plus.circle")
actions.append(UIAction(title: commitTitle, image: commitImage, identifier: UIAction.Identifier("commit"), handler: handler))
}
if UserDefaultsManagement.autoVersioning && !note.isEncrypted() {
let historyTitle = NSLocalizedString("History", comment: "")
let historyImage = UIImage(systemName: "clock.arrow.circlepath")
actions.append(UIAction(title: historyTitle, image: historyImage, identifier: UIAction.Identifier("history"), handler: handler))
}
let renameTitle = NSLocalizedString("Rename", comment: "")
let renameImage = UIImage(systemName: "pencil.circle")
actions.append(UIAction(title: renameTitle, image: renameImage, identifier: UIAction.Identifier("rename"), handler: handler))
let pinUnpinTitle = note.isPinned ? NSLocalizedString("Unpin", comment: "") : NSLocalizedString("Pin", comment: "")
let pinUnpinImage = UIImage(systemName: note.isPinned ? "pin.slash" : "pin")
actions.append(UIAction(title: pinUnpinTitle, image: pinUnpinImage, identifier: UIAction.Identifier("pinUnpin"), handler: handler))
let lockUnlockTitle =
(note.isUnlocked() && note.isEncrypted()) || !note.isEncrypted()
? NSLocalizedString("Lock", comment: "")
: NSLocalizedString("Unlock", comment: "")
let lockUnlockImageName = (note.isUnlocked() && note.isEncrypted()) || !note.isEncrypted()
? "lock"
: "lock.open"
let lockUnlockImage = UIImage(systemName: lockUnlockImageName)
actions.append(UIAction(title: lockUnlockTitle, image: lockUnlockImage, identifier: UIAction.Identifier("lockUnlock"), handler: handler))
if note.isEncrypted() && !note.project.isEncrypted {
let removeEncryptionTitle = NSLocalizedString("Remove Encryption", comment: "")
let removeEncryptionImage = UIImage(systemName: "lock.slash")
actions.append(UIAction(title: removeEncryptionTitle, image: removeEncryptionImage, identifier: UIAction.Identifier("removeEncryption"), handler: handler))
}
var clipboardName = "doc.on.clipboard"
if #available(iOS 16.0, *) {
clipboardName = "clipboard"
}
let copyTitle = NSLocalizedString("Copy Plain Text", comment: "")
let copyImage = UIImage(systemName: clipboardName)
actions.append(UIAction(title: copyTitle, image: copyImage, identifier: UIAction.Identifier("copy"), handler: handler))
let shareTitle = NSLocalizedString("Share", comment: "")
let shareImage = UIImage(systemName: "square.and.arrow.up")
actions.append(UIAction(title: shareTitle, image: shareImage, identifier: UIAction.Identifier("share"), handler: handler))
var shareWebTitle = NSLocalizedString("Create Web Page", comment: "")
if note.apiId != nil {
shareWebTitle = NSLocalizedString("Update Web Page", comment: "")
}
let shareWebImage = UIImage(systemName: "newspaper")
actions.append(UIAction(title: shareWebTitle, image: shareWebImage, identifier: UIAction.Identifier("shareWeb"), handler: handler))
if note.apiId != nil {
let deleteWebTitle = NSLocalizedString("Delete Web Page", comment: "")
let deleteWebImage = UIImage(systemName: "newspaper.fill")
actions.append(UIAction(title: deleteWebTitle, image: deleteWebImage, identifier: UIAction.Identifier("deleteWeb"), handler: handler))
}
return UIMenu(title: note.getShortTitle(), children: actions)
}
func scrollViewShouldScrollToTop(_ scrollView: UIScrollView) -> Bool {
setContentOffset(CGPoint(x: 0, y: -44), animated: true)
return false
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
viewDelegate?.navigationItem.hidesSearchBarWhenScrolling = false
viewDelegate?.navigationItem.largeTitleDisplayMode = .automatic
}
public func actionsSheet(notes: [Note], showAll: Bool = false, presentController: UIViewController, back: Bool = false) {
let note = notes.first!
let actionSheet = UIAlertController(title: note.project.getFullLabel() + " ➔ " + note.url.lastPathComponent, message: nil, preferredStyle: .actionSheet)
let remove = UIAlertAction(title: NSLocalizedString("Delete", comment: ""), style: .destructive, handler: { _ in
self.turnOffEditing()
self.removeAction(notes: notes)
if presentController.isKind(of: EditorViewController.self) || back {
UIApplication.getEVC().cancel()
}
})
remove.setValue(CATextLayerAlignmentMode.left, forKey: "titleTextAlignment")
if let image = UIImage(systemName: "trash")?.resize(maxWidthHeight: 23) {
remove.setValue(image, forKey: "image")
}
actionSheet.addAction(remove)
if showAll && note.hasGitRepository() && !note.isEncrypted() {
let history = UIAlertAction(title: NSLocalizedString("Save Revision", comment: ""), style: .default, handler: { _ in
self.saveRevisionAction(note: notes.first!)
})
history.setValue(CATextLayerAlignmentMode.left, forKey: "titleTextAlignment")
if let image = UIImage(systemName: "plus.circle")?.resize(maxWidthHeight: 23) {
history.setValue(image, forKey: "image")
}
actionSheet.addAction(history)
}
if showAll && UserDefaultsManagement.autoVersioning && !note.isEncrypted() {
let history = UIAlertAction(title: NSLocalizedString("History", comment: ""), style: .default, handler: { _ in
self.historyAction(note: notes.first!)
})
history.setValue(CATextLayerAlignmentMode.left, forKey: "titleTextAlignment")
if let image = UIImage(systemName: "clock.arrow.circlepath")?.resize(maxWidthHeight: 23) {
history.setValue(image, forKey: "image")
}
actionSheet.addAction(history)
}
let creationDate = UIAlertAction(title: NSLocalizedString("Change Creation Date", comment: ""), style: .default, handler: { _ in
self.dateAction(notes: notes)
})
creationDate.setValue(CATextLayerAlignmentMode.left, forKey: "titleTextAlignment")
if let image = UIImage(systemName: "calendar")?.resize(maxWidthHeight: 23) {
creationDate.setValue(image, forKey: "image")
}
actionSheet.addAction(creationDate)
let duplicate = UIAlertAction(title: NSLocalizedString("Duplicate", comment: ""), style: .default, handler: { _ in
self.duplicateAction(notes: notes)
})
duplicate.setValue(CATextLayerAlignmentMode.left, forKey: "titleTextAlignment")
if let image = UIImage(systemName: "doc.on.doc")?.resize(maxWidthHeight: 23) {
duplicate.setValue(image, forKey: "image")
}
actionSheet.addAction(duplicate)
if showAll {
let rename = UIAlertAction(title: NSLocalizedString("Rename", comment: ""), style: .default, handler: { _ in
self.renameAction(note: note)
})
rename.setValue(CATextLayerAlignmentMode.left, forKey: "titleTextAlignment")
if let image = UIImage(systemName: "pencil.circle")?.resize(maxWidthHeight: 23) {
rename.setValue(image, forKey: "image")
}
actionSheet.addAction(rename)
let title = note.isPinned ? NSLocalizedString("Unpin", comment: "") : NSLocalizedString("Pin", comment: "")
let pin = UIAlertAction(title: title, style: .default, handler: { _ in
if note.isPinned {
note.removePin()
self.removePins(notes: [note])
} else {
note.addPin()
self.addPins(notes: [note])
}
})
pin.setValue(CATextLayerAlignmentMode.left, forKey: "titleTextAlignment")
if let image = UIImage(systemName: note.isPinned ? "pin.slash" : "pin")?.resize(maxWidthHeight: 23) {
pin.setValue(image, forKey: "image")
}
actionSheet.addAction(pin)
}
let move = UIAlertAction(title: NSLocalizedString("Move", comment: ""), style: .default, handler: { _ in
self.turnOffEditing()
self.moveAction(notes: notes)
})
move.setValue(CATextLayerAlignmentMode.left, forKey: "titleTextAlignment")
if let image = UIImage(systemName: "move.3d")?.resize(maxWidthHeight: 23) {
move.setValue(image, forKey: "image")
}
actionSheet.addAction(move)
if showAll {
let alertTitle =
(note.isUnlocked() && note.isEncrypted()) || !note.isEncrypted()
? NSLocalizedString("Lock", comment: "")
: NSLocalizedString("Unlock", comment: "")
let imageName = (note.isUnlocked() && note.isEncrypted()) || !note.isEncrypted()
? "lock"
: "lock.open"
let encryption = UIAlertAction(title: alertTitle, style: .default, handler: { _ in
self.viewDelegate?.toggleNotesLock(notes: [note])
if !note.isUnlocked(), presentController.isKind(of: EditorViewController.self) || back {
UIApplication.getEVC().cancel()
}
})
encryption.setValue(CATextLayerAlignmentMode.left, forKey: "titleTextAlignment")
if let image = UIImage(systemName: imageName)?.resize(maxWidthHeight: 23) {
encryption.setValue(image, forKey: "image")
}
actionSheet.addAction(encryption)
if note.isEncrypted() {
let removeEncryption = UIAlertAction(title: NSLocalizedString("Remove Encryption", comment: ""), style: .default, handler: { _ in
self.removeEncryption(note: note)
})
removeEncryption.setValue(CATextLayerAlignmentMode.left, forKey: "titleTextAlignment")
if let image = UIImage(systemName: "lock.slash")?.resize(maxWidthHeight: 23) {
removeEncryption.setValue(image, forKey: "image")
}
actionSheet.addAction(removeEncryption)
}
var clipboardName = "doc.on.clipboard"
if #available(iOS 16.0, *) {
clipboardName = "clipboard"
}
let copy = UIAlertAction(title: NSLocalizedString("Copy Plain Text", comment: ""), style: .default, handler: { _ in
self.copyAction(note: note)
})
copy.setValue(CATextLayerAlignmentMode.left, forKey: "titleTextAlignment")
if let image = UIImage(systemName: clipboardName)?.resize(maxWidthHeight: 23) {
copy.setValue(image, forKey: "image")
}
actionSheet.addAction(copy)
let share = UIAlertAction(title: NSLocalizedString("Share", comment: ""), style: .default, handler: { _ in
self.shareAction(note: note)
})
share.setValue(CATextLayerAlignmentMode.left, forKey: "titleTextAlignment")
if let image = UIImage(systemName: "square.and.arrow.up")?.resize(maxWidthHeight: 23) {
share.setValue(image, forKey: "image")
}
actionSheet.addAction(share)
}
let dismiss = UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .cancel, handler: { _ in
if self.isEditing {
self.setEditing(false, animated: true)
}
})
actionSheet.addAction(dismiss)
if let view = UIApplication.getEVC().view {
actionSheet.popoverPresentationController?.sourceView = view
actionSheet.popoverPresentationController?.sourceRect = CGRect(x: view.bounds.size.width / 2.0, y: view.bounds.size.height, width: 2.0, height: 1.0)
}
presentController.present(actionSheet, animated: true, completion: nil)
}
public func removeRows(notes: [Note]) {
guard notes.count > 0, let vc = viewDelegate, vc.isNoteInsertionAllowed() else { return }
vc.removeSpotlightIndex(notes: notes)
var indexPaths = [IndexPath]()
var tags = [String]()
for note in notes {
if let i = self.notes.firstIndex(where: { $0 === note }) {
indexPaths.append(IndexPath(row: i, section: 0))
tags.append(contentsOf: note.tags)
}
}
beginUpdates()
self.notes.removeAll(where: { notes.contains($0) })
deleteRows(at: indexPaths, with: .automatic)
endUpdates()
vc.updateNotesCounter()
vc.sidebarTableView.delete(tags: tags)
}
public func insertRows(notes: [Note]) {
guard notes.count > 0, let vc = viewDelegate, vc.isNoteInsertionAllowed() else { return }
vc.storage.loadPins(notes: notes)
var toInsert = [Note]()
for note in notes {
guard vc.storage.searchQuery.isFit(note: note),
!self.notes.contains(where: { $0 === note })
else { continue }
toInsert.append(note)
}
guard toInsert.count > 0 else { return }
vc.updateSpotlightIndex(notes: toInsert)
let nonSorted = self.notes + toInsert
let sorted = vc.storage.sortNotes(noteList: nonSorted)
var indexPaths = [IndexPath]()
for note in toInsert {
guard let index = sorted.firstIndex(where: { $0 === note }) else { continue }
indexPaths.append(IndexPath(row: index, section: 0))
}
self.notes = sorted
beginUpdates()
insertRows(at: indexPaths, with: .fade)
endUpdates()
}
public func reloadRows(notes: [Note], resetKeys: Bool = false) {
beginUpdates()
for note in notes {
if let row = self.notes.firstIndex(where: { $0 === note }) {
let indexPath = IndexPath(row: row, section: 0)
if let cell = cellForRow(at: indexPath) as? NoteCellView {
if resetKeys {
cell.imageKeys = []
}
cell.configure(note: note)
cell.updateView()
}
}
}
endUpdates()
viewDelegate?.updateSpotlightIndex(notes: notes)
}
public func reloadRowForce(note: Note) {
note.invalidateCache()
note.loadPreviewInfo()
if let index = notes.firstIndex(of: note) {
reloadRows(at: [IndexPath(row: index, section: 0)], with: .automatic)
}
}
private func renameAction(note: Note) {
let alertController = UIAlertController(title: NSLocalizedString("Rename note:", comment: ""), message: nil, preferredStyle: .alert)
alertController.addTextField(configurationHandler: {
[] (textField: UITextField) in
textField.placeholder = NSLocalizedString("Enter note name", comment: "")
textField.attributedText = NSAttributedString(string: note.getFileName())
})
let confirmAction = UIAlertAction(title: "OK", style: .default) { (_) in
guard let name = alertController.textFields?[0].text, name.count > 0 else {
return
}
self.rename(note: note, to: name)
}
let title = NSLocalizedString("Cancel", comment: "")
let cancelAction = UIAlertAction(title: title, style: .cancel) { (_) in }
alertController.addAction(confirmAction)
alertController.addAction(cancelAction)
UIApplication.getNC()?.present(alertController, animated: true) {
alertController.textFields![0].selectAll(nil)
}
}
public func rename(note: Note, to name: String) {
guard name.count > 0, name.trim().count > 0 else { return }
var name = name
var i = 1
while note.project.fileExistCaseInsensitive(fileName: name, ext: note.url.pathExtension) {
// disables renaming loop
if note.fileName.startsWith(string: name) {
return
}
let items = name.split(separator: " ")
if let last = items.last, let position = Int(last) {
let full = items.dropLast()
name = full.joined(separator: " ") + " " + String(position + 1)
i = position + 1
} else {
name = name + " " + String(i)
i += 1
}
}
let isPinned = note.isPinned
let dst = note.getNewURL(name: name)
let src = note.url
note.removePin()
if note.isEncrypted() {
_ = note.lock()
}
if note.move(to: dst) {
note.url = dst
note.parseURL()
note.moveHistory(src: src, dst: dst)
}
if isPinned {
note.addPin()
}
DispatchQueue.main.async {
self.reloadRows(notes: [note])
}
}
public func removeAction(notes: [Note]) {
guard let vc = viewDelegate else { return }
vc.sidebarTableView.removeTags(in: notes)
for note in notes {
note.remove()
}
removeRows(notes: notes)
allowsMultipleSelectionDuringEditing = false
setEditing(false, animated: true)
}
public func moveAction(notes: [Note]) {
let moveController = MoveViewController(notes: notes, notesTableView: self)
let controller = UINavigationController(rootViewController: moveController)
let nvc = UIApplication.getNC()
nvc?.present(controller, animated: true, completion: nil)
}
public func dateAction(notes: [Note]) {
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let datePickerViewController = storyBoard.instantiateViewController(withIdentifier: "datePickerViewController") as! DatePickerViewController
datePickerViewController.notes = notes
let nvc = UIApplication.getNC()
nvc?.present(datePickerViewController, animated: true )
}
public func showLoader() {
let alert = UIAlertController(title: nil, message: " ", preferredStyle: .alert)
let loadingIndicator = UIActivityIndicatorView(style: .large)
loadingIndicator.translatesAutoresizingMaskIntoConstraints = false
loadingIndicator.startAnimating()
let label = UILabel()
label.text = NSLocalizedString("Loading...", comment: "")
label.font = UIFont.preferredFont(forTextStyle: .title2)
label.adjustsFontForContentSizeCategory = true
label.numberOfLines = 1
label.translatesAutoresizingMaskIntoConstraints = false
let stack = UIStackView(arrangedSubviews: [loadingIndicator, label])
stack.axis = .horizontal
stack.spacing = 14
stack.alignment = .center
stack.translatesAutoresizingMaskIntoConstraints = false
alert.view.addSubview(stack)
NSLayoutConstraint.activate([
stack.centerXAnchor.constraint(equalTo: alert.view.centerXAnchor),
stack.centerYAnchor.constraint(equalTo: alert.view.centerYAnchor, constant: 6),
stack.leadingAnchor.constraint(greaterThanOrEqualTo: alert.view.leadingAnchor, constant: 20),
stack.trailingAnchor.constraint(lessThanOrEqualTo: alert.view.trailingAnchor, constant: -20),
])
UIApplication.getNC()?.present(alert, animated: true)
}
public func hideLoader() {
DispatchQueue.main.async {
UIApplication.getNC()?.dismiss(animated: false, completion: nil)
}
}
public func saveRevisionAction(note: Note? = nil, project: Project? = nil) {
var current: Project?
if let unwrappedProject = project {
current = unwrappedProject
} else if let note = note {
current = note.getGitProject()
}
guard let project = current else { return }
guard let nvc = UIApplication.getNC() else { return }
let viewController = UIApplication.getVC()
// Show loader
let title = NSLocalizedString("Loading...", comment: "")
let alert = UIAlertController(title: nil, message: title, preferredStyle: .alert)
let loadingIndicator = UIActivityIndicatorView(frame: CGRect(x: 10, y: 5, width: 50, height: 50))
loadingIndicator.hidesWhenStopped = true
loadingIndicator.style = UIActivityIndicatorView.Style.medium
loadingIndicator.startAnimating();
alert.view.addSubview(loadingIndicator)
nvc.present(alert, animated: true)
DispatchQueue.global(qos: .userInitiated).async {
do {
try project.saveRevision()
// Hide loader
DispatchQueue.main.async {
nvc.dismiss(animated: false, completion: nil)
}
} catch GitError.noAddedFiles {
DispatchQueue.main.async {
// Hide loader
nvc.dismiss(animated: false, completion: nil)
let alert = UIAlertController(title: "No changes", message: "Nothing new to commit", preferredStyle: UIAlertController.Style.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
nvc.present(alert, animated: true, completion: nil)
}
} catch {
DispatchQueue.main.async {
// Hide loader
nvc.dismiss(animated: false, completion: nil)
project.gitStatus = error.localizedDescription
let alert = UIAlertController(title: "Git error", message: error.localizedDescription, preferredStyle: UIAlertController.Style.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
nvc.present(alert, animated: true, completion: nil)
}
return
}
if project.isGitOriginExist() {
viewController.gitQueue.addOperation({
try? project.pull()
try? project.push()
})
}
}
}
private func historyAction(note: Note) {
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let datePickerViewController = storyBoard.instantiateViewController(withIdentifier: "revisionsViewController") as! RevisionsViewController
datePickerViewController.note = note
UIApplication.getNC()?.present(datePickerViewController, animated: true)
}
private func copyAction(note: Note) {
let item = [kUTTypeUTF8PlainText as String : note.content.string as Any]
UIPasteboard.general.items = [item]
}
public func shareAction(note: Note, isHTML: Bool = false) {
AudioServicesPlaySystemSound(1519)
var tempURL = note.url
if note.isTextBundle() {
tempURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("\(note.getName()).zip")
SSZipArchive.createZipFile(atPath: tempURL.path, withContentsOfDirectory: note.url.path, keepParentDirectory: true)
}
let objectsToShare = [tempURL] as [Any]
let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
activityVC.excludedActivityTypes = [ UIActivity.ActivityType.addToReadingList ]
guard let presentController = UIApplication.getNC() else { return }
presentController.present(activityVC, animated: true, completion: nil)
guard let popOver = activityVC.popoverPresentationController else { return }
popOver.permittedArrowDirections = .up
let notesTable = UIApplication.getVC().notesTable
let editorView = UIApplication.getEVC().editArea
if let topViewController = presentController.topViewController {
if topViewController.isKind(of: EditorViewController.self) {
popOver.sourceView = editorView
popOver.sourceRect = CGRect(x: editorView!.bounds.midX, y: 80, width: 0, height: 0)
} else if topViewController.isKind(of: ViewController.self),
let i = notesTable?.notes.firstIndex(where: {$0 === note}),
let rowView = notesTable?.cellForRow(at: IndexPath(row: i, section: 0)) {
popOver.sourceView = rowView
popOver.sourceRect = CGRect(x: notesTable!.bounds.midX, y: rowView.frame.height, width: 10, height: 10)
}
}
}
public func duplicateAction(notes: [Note]) {
var dupes = [Note]()
for note in notes {
let src = note.url
let dst = NameHelper.generateCopy(file: note.url)
if note.isTextBundle() || note.isEncrypted() {
try? FileManager.default.copyItem(at: src, to: dst)
let noteDupe = Note(url: dst, with: note.project)
noteDupe.load()
viewDelegate?.storage.add(noteDupe)
dupes.append(noteDupe)
continue
}
let name = dst.deletingPathExtension().lastPathComponent
let noteDupe = Note(name: name, project: note.project, type: note.type, cont: note.container)
noteDupe.content = NSMutableAttributedString(string: note.content.string)
// Clone images
if note.type == .Markdown && note.container == .none {
let images = note.content.getImagesAndFiles()
for image in images {
noteDupe.move(from: image.url, imagePath: image.path, to: note.project, copy: true)
}
}
if noteDupe.save() {
Storage.shared().add(noteDupe)
}
dupes.append(noteDupe)
}
insertRows(notes: dupes)
if let scrollTo = dupes.first {
viewDelegate?.notesTable.scrollTo(note: scrollTo)
}
}
private func decryptUnlocked(notes: [Note]) -> [Note] {
var notes = notes
var toReload = [Note]()
for note in notes {
if note.isUnlocked() {
if note.unEncryptUnlocked() {
notes.removeAll { $0 === note }
toReload.append(note)
note.invalidateCache()
}
}
}
DispatchQueue.main.async {
self.reloadRows(notes: toReload, resetKeys: true)
}
return notes
}
public func removeEncryption(note: Note) {
let vc = UIApplication.getVC()
let notes = decryptUnlocked(notes: [note])
guard let note = notes.first else { return }
vc.getMasterPassword() { password in
if note.container == .encryptedTextPack {
let success = note.unEncrypt(password: password)
note.password = nil
if success {
DispatchQueue.main.async {
UIApplication.getEVC().refill()
}
} else {
self.askPasswordAndUnEncrypt(note: note)
return
}
}
DispatchQueue.main.async {
self.reloadRows(notes: notes, resetKeys: true)
}
}
}
public func shareWebAction(note: Note) {
UIApplication.getVC().createAPI(note: note, completion: { url in
DispatchQueue.main.async {
self.reloadRowForce(note: note)
if let url = url {
UIApplication.shared.open(url)
}
UIApplication.getEVC().configureNavMenu()
}
})
}
public func deleteWebAction(note: Note) {
UIApplication.getVC().deleteAPI(note: note, completion: {
DispatchQueue.main.async {
self.reloadRowForce(note: note)
UIApplication.getEVC().configureNavMenu()
}
})
}
public func moveRowUp(note: Note) {
guard let vc = viewDelegate,
vc.isNoteInsertionAllowed(),
vc.storage.searchQuery.isFit(note: note)
else { return }
guard let currentIndex = notes.firstIndex(where: { $0 === note }) else { return }
let sorted = vc.storage.sortNotes(noteList: notes)
guard let targetIndex = sorted.firstIndex(where: { $0 === note }) else { return }
guard currentIndex != targetIndex else { return }
self.notes = sorted
let from = IndexPath(row: currentIndex, section: 0)
let to = IndexPath(row: targetIndex, section: 0)
beginUpdates()
moveRow(at: from, to: to)
endUpdates()
}
@objc public func toggleSelectAll() {
guard self.isEditing else { return }
if let selected = self.indexPathsForSelectedRows, (selected.count - 1) == self.notes.count {
for indexPath in selected {
self.deselectRow(at: indexPath, animated: false)
}
self.selectedIndexPaths = nil
} else {
for i in 0...notes.count {
self.selectRow(at: IndexPath(item: i, section: 0), animated: false, scrollPosition: .none)
}
self.selectedIndexPaths = indexPathsForSelectedRows
}
}
private func invalidPasswordAlert() {
let invalid = NSLocalizedString("Invalid Password", comment: "")
let message = NSLocalizedString("Please enter valid password", comment: "")
let alert = UIAlertController(title: invalid, message: message, preferredStyle: UIAlertController.Style.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
UIApplication.getVC().present(alert, animated: true, completion: nil)
}
func tableView(_ tableView: UITableView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
guard let cell = tableView.cellForRow(at: indexPath) as? NoteCellView,
let url = cell.note?.url
else { return [] }
let itemProvider = NSItemProvider(item: url as NSSecureCoding, typeIdentifier: kUTTypeURL as String)
return [UIDragItem(itemProvider: itemProvider)]
}
public func addPins(notes pinned: [Note]) {
guard let vc = viewDelegate else { return }
let oldNotes = self.notes
let newNotes = vc.storage.sortNotes(noteList: oldNotes)
self.notes = newNotes
var rowsToReload: [IndexPath] = []
beginUpdates()
for note in pinned {
guard
let from = oldNotes.firstIndex(of: note),
let to = newNotes.firstIndex(of: note),
from != to
else { continue }
moveRow(
at: IndexPath(row: from, section: 0),
to: IndexPath(row: to, section: 0)
)
rowsToReload.append(IndexPath(row: to, section: 0))
}
endUpdates()
if !rowsToReload.isEmpty {
reloadRows(at: rowsToReload, with: .none)
}
}
public func removePins(notes unpinned: [Note]) {
guard let vc = viewDelegate else { return }
let oldNotes = self.notes
let newNotes = vc.storage.sortNotes(noteList: oldNotes)
self.notes = newNotes
var rowsToReload: [IndexPath] = []
beginUpdates()
for note in unpinned {
guard
let from = oldNotes.firstIndex(of: note),
let to = newNotes.firstIndex(of: note),
from != to
else { continue }
moveRow(
at: IndexPath(row: from, section: 0),
to: IndexPath(row: to, section: 0)
)
rowsToReload.append(IndexPath(row: to, section: 0))
}
endUpdates()
if !rowsToReload.isEmpty {
reloadRows(at: rowsToReload, with: .none)
}
}
public func scrollTo(note: Note) {
if let index = notes.firstIndex(of: note) {
let indexPath = IndexPath(row: index, section: 0)
scrollToRow(at: indexPath, at: .top, animated: true)
}
}
public func doVisualChanges(results: ([Note], [Note], [Note])) {
guard results.0.count > 0 || results.1.count > 0 || results.2.count > 0 else {
return
}
DispatchQueue.main.async {
self.removeRows(notes: results.0)
self.insertRows(notes: results.1)
self.reloadRows(notes: results.2)
}
}
}
================================================
FILE: FSNotes iOS/View/SidebarTableCellView.swift
================================================
//
// SidebarTableCellView.swift
// FSNotes iOS
//
// Created by Oleksandr Glushchenko on 5/5/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import UIKit
class SidebarTableCellView: UITableViewCell {
@IBOutlet weak var icon: UIImageView!
@IBOutlet weak var label: UILabel!
@IBOutlet weak var labelConstraint: NSLayoutConstraint!
public var sidebarItem: SidebarItem?
func configure(sidebarItem: SidebarItem) {
self.sidebarItem = sidebarItem
self.icon.constraints[1].constant = 21
self.labelConstraint.constant = 11
icon.image = sidebarItem.icon
var font = UIFont.systemFont(ofSize: 15)
if sidebarItem.type == .Project ||
sidebarItem.type == .ProjectEncryptedLocked ||
sidebarItem.type == .ProjectEncryptedUnlocked ||
sidebarItem.type == .Tag {
font = UIFont.systemFont(ofSize: 14)
}
let fontMetrics = UIFontMetrics(forTextStyle: .title3)
font = fontMetrics.scaledFont(for: font)
label.font = font
label.text = sidebarItem.name
}
override func layoutSubviews() {
super.layoutSubviews()
self.selectedBackgroundView?.backgroundColor = UIColor.currentSidebarCell
self.selectedBackgroundView?.frame = CGRect(x: 0, y: 0, width: 5, height: 40)
}
}
================================================
FILE: FSNotes iOS/View/SidebarTableView.swift
================================================
//
// SidebarTableView.swift
// FSNotes iOS
//
// Created by Oleksandr Glushchenko on 5/5/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import Foundation
import UIKit
import AudioToolbox
class SidebarTableView: UITableView,
UITableViewDelegate,
UITableViewDataSource,
UITableViewDropDelegate {
public var sidebar = Sidebar()
private var busyTrashReloading = false
public var viewController: ViewController?
func numberOfSections(in tableView: UITableView) -> Int {
return sidebar.items.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sidebar.items[section].count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "sidebarCell", for: indexPath) as! SidebarTableCellView
guard sidebar.items.indices.contains(indexPath.section), sidebar.items[indexPath.section].indices.contains(indexPath.row) else { return cell }
let sidebarItem = sidebar.items[indexPath.section][indexPath.row]
cell.configure(sidebarItem: sidebarItem)
cell.contentView.setNeedsLayout()
cell.contentView.layoutIfNeeded()
return cell
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if section == 0 {
return UIView()
}
return nil
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
if section == 0 {
return 5
}
if section == 1 && UIApplication.getVC().storage.getNonSystemProjects().count == 0 {
return 0
}
return 25
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 0
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 37
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
selectRow(at: indexPath, animated: false, scrollPosition: .none)
self.tableView(tableView, didSelectRowAt: indexPath)
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
guard let vc = self.viewController else { return }
let selectedSection = SidebarSection(rawValue: indexPath.section)
guard sidebar.items.indices.contains(indexPath.section) && sidebar.items[indexPath.section].indices.contains(indexPath.row) else { return }
let sidebarItem = sidebar.items[indexPath.section][indexPath.row]
guard vc.storage.searchQuery.projects.first != sidebarItem.project
|| sidebarItem.type == .Tag else { return }
if let project = vc.storage.searchQuery.projects.first, getIndexPathBy(project: project) == indexPath, vc.notesTable.isEditing {
vc.notesTable.toggleSelectAll()
return
}
if let project = sidebarItem.project, project.isLocked() {
vc.enableLockedProject()
} else {
vc.disableLockedProject()
}
guard sidebar.items.indices.contains(indexPath.section) && sidebar.items[indexPath.section].indices.contains(indexPath.row) else {
return
}
vc.notesTable.turnOffEditing()
var name = sidebarItem.name
if sidebarItem.type == .Tag {
name = "#\(name)"
}
if selectedSection == .Tags {
deselectAllTags()
} else {
deselectAllProjects()
deselectAllTags()
}
selectRow(at: indexPath, animated: false, scrollPosition: .none)
vc.configureNavMenu(for: sidebarItem)
vc.navigationItem.searchController?.searchBar.text = ""
// Save last state
if sidebarItem.isSystem() {
UserDefaultsManagement.lastSidebarItem = indexPath.row
UserDefaultsManagement.lastProjectURL = nil
} else if let project = sidebarItem.project, !project.isVirtual {
UserDefaultsManagement.lastSidebarItem = nil
UserDefaultsManagement.lastProjectURL = project.url
}
vc.buildSearchQuery()
vc.reloadNotesTable() {
DispatchQueue.main.async {
vc.notesTable.hideLoader()
vc.setNavTitle(folder: name)
vc.isLoadedSidebar = true
guard vc.notesTable.notes.count > 0 else {
self.unloadAllTags()
return
}
let path = IndexPath(row: 0, section: 0)
vc.notesTable.scrollToRow(at: path, at: .top, animated: true)
if selectedSection != .Tags {
self.loadAllTags()
vc.resizeSidebar(withAnimation: true)
}
}
}
}
func tableView(_ tableView: UITableView, contextMenuConfigurationForRowAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? {
return UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { suggestedActions in
let sidebarItem = self.sidebar.items[indexPath.section][indexPath.row]
let menu = self.viewController!.makeSidebarSettingsMenu(for: sidebarItem)
return menu
}
}
public func selectCurrentProject() {
guard let vc = self.viewController else { return }
var indexPath: IndexPath = IndexPath(row: 0, section: 0)
if let type = vc.storage.searchQuery.type,
let ip = getIndexPathBy(type: type) {
indexPath = ip
} else if let project = vc.storage.searchQuery.projects.first,
let ip = getIndexPathBy(project: project) {
indexPath = ip
}
let sidebarItem = sidebar.items[indexPath.section][indexPath.row]
let name = sidebarItem.name
selectRow(at: indexPath, animated: false, scrollPosition: .none)
vc.configureNavMenu(for: sidebarItem)
vc.buildSearchQuery()
vc.reloadNotesTable() {
DispatchQueue.main.async {
vc.setNavTitle(folder: name)
}
}
}
private func deselectAllTags() {
if let selectedIndexPaths = indexPathsForSelectedRows {
for indexPathItem in selectedIndexPaths {
if indexPathItem.section == SidebarSection.Tags.rawValue {
deselectRow(at: indexPathItem, animated: false)
}
}
}
}
private func deselectAllProjects() {
if let selectedIndexPaths = indexPathsForSelectedRows {
for indexPathItem in selectedIndexPaths {
if indexPathItem.section == SidebarSection.Projects.rawValue
|| indexPathItem.section == SidebarSection.System.rawValue {
deselectRow(at: indexPathItem, animated: false)
}
}
}
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
cell.backgroundColor = UIColor.clear
}
public func deselectAll() {
if let paths = indexPathsForSelectedRows {
for path in paths {
deselectRow(at: path, animated: false)
}
}
}
public func getSidebarItem(project: Project? = nil) -> SidebarItem? {
if let project = project, sidebar.items.count > 1 {
return sidebar.items[1].first(where: { $0.project == project })
}
guard let indexPath = indexPathForSelectedRow else { return nil }
let item = sidebar.items[indexPath.section][indexPath.row]
return item
}
func tableView(_ tableView: UITableView, performDropWith coordinator: UITableViewDropCoordinator) {
guard let vc = viewController else { return }
guard let indexPath = coordinator.destinationIndexPath, let cell = tableView.cellForRow(at: indexPath) as? SidebarTableCellView else { return }
guard let sidebarItem = cell.sidebarItem else { return }
_ = coordinator.session.loadObjects(ofClass: URL.self) { item in
let pathList = item as [URL]
for url in pathList {
guard let note = Storage.shared().getBy(url: url) else { continue }
switch sidebarItem.type {
case .Project, .Inbox:
guard let project = sidebarItem.project else { break }
self.move(note: note, in: project)
case .Trash:
note.remove()
vc.notesTable.removeRows(notes: [note])
default:
break
}
}
vc.notesTable.isEditing = false
vc.navigationController?.setToolbarHidden(true, animated: true)
}
}
func tableView(_ tableView: UITableView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UITableViewDropProposal {
guard let indexPath = destinationIndexPath,
let cell = tableView.cellForRow(at: indexPath) as? SidebarTableCellView,
let sidebarItem = cell.sidebarItem
else { return UITableViewDropProposal(operation: .cancel) }
if sidebarItem.project != nil || sidebarItem.type == .Trash {
return UITableViewDropProposal(operation: .copy)
}
return UITableViewDropProposal(operation: .cancel)
}
private func move(note: Note, in project: Project) {
guard let vc = viewController else { return }
let dstURL = project.url.appendingPathComponent(note.name)
if note.project != project {
note.moveImages(to: project)
if note.isEncrypted() {
_ = note.lock()
}
guard note.move(to: dstURL) else {
let alert = UIAlertController(title: "Oops 👮♂️", message: "File with this name already exist", preferredStyle: UIAlertController.Style.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
vc.present(alert, animated: true, completion: nil)
note.moveImages(to: note.project)
return
}
note.moveHistory(src: note.url, dst: dstURL)
note.url = dstURL
note.parseURL()
note.project = project
// resets tags in sidebar
removeTags(in: [note])
// reload tags (in remove tags operation non fitted)
_ = note.scanContentTags()
vc.notesTable.removeRows(notes: [note])
vc.notesTable.insertRows(notes: [note])
}
}
public func getSidebarProjects() -> [Project]? {
guard let indexPaths = UIApplication.getVC().sidebarTableView?.indexPathsForSelectedRows else { return nil }
var projects = [Project]()
for indexPath in indexPaths {
let item = sidebar.items[indexPath.section][indexPath.row]
if let project = item.project {
projects.append(project)
}
}
if projects.count > 0 {
return projects
}
if let root = Storage.shared().getDefault() {
return [root]
}
return nil
}
public func getAllTags(projects: [Project]? = nil) -> [String] {
var tags = [String]()
if let projects = projects {
for project in projects {
let projectTags = project.getAllTags()
for tag in projectTags {
if !tags.contains(tag) {
tags.append(tag)
}
}
}
}
return tags.sorted()
}
private func getAllTags(notes: [Note]? = nil) -> [String] {
var tags = [String]()
if let notes = notes {
for note in notes {
for tag in note.tags {
if !tags.contains(tag) {
tags.append(tag)
}
}
}
}
return tags.sorted()
}
public func loadAllTags() {
guard UserDefaultsManagement.inlineTags, let vc = viewController else { return }
unloadAllTags()
let notes = vc.notesTable.notes
let tags = getAllTags(notes: notes)
guard tags.count > 0, self.sidebar.items.indices.contains(2) else { return }
var indexPaths = [IndexPath]()
for tag in tags {
let position = self.sidebar.items[2].count
let element = SidebarItem(name: tag, type: .Tag)
self.sidebar.items[2].insert(element, at: position)
indexPaths.append(IndexPath(row: position, section: 2))
}
insertRows(at: indexPaths, with: .automatic)
}
public func unloadAllTags() {
guard sidebar.items.indices.contains(2), sidebar.items[2].count > 0 else { return }
let rows = numberOfRows(inSection: 2)
if rows > 0 {
self.sidebar.items[2].removeAll()
var indexPaths = [IndexPath]()
for index in stride(from: rows - 1, to: -1, by: -1) {
indexPaths.append(IndexPath(row: index, section: 2))
}
deleteRows(at: indexPaths, with: .automatic)
}
}
public func removeTags(in notes: [Note]) {
for note in notes {
note.tags.removeAll()
}
loadTags(notes: notes)
}
public func loadTags(notes: [Note]) {
var toInsert = [String]()
var toDelete = [String]()
for note in notes {
guard let query = createQueryWithoutTags(), query.isFit(note: note) else { continue }
let result = note.scanContentTags()
if result.0.count > 0 {
toInsert.append(contentsOf: result.0)
}
if result.1.count > 0 {
toDelete.append(contentsOf: result.1)
note.tags.removeAll(where: { result.1.contains($0) })
}
}
toInsert = Array(Set(toInsert))
toDelete = Array(Set(toDelete))
insert(tags: toInsert)
delete(tags: toDelete)
}
public func insert(tags: [String]) {
let currentTags = sidebar.items[2].compactMap({ $0.name })
var toInsert = [String]()
for tag in tags {
if currentTags.contains(tag) {
continue
}
toInsert.append(tag)
}
guard toInsert.count > 0 else { return }
let nonSorted = currentTags + toInsert
let sorted = nonSorted.sorted()
var indexPaths = [IndexPath]()
for tag in toInsert {
guard let index = sorted.firstIndex(of: tag) else { continue }
indexPaths.append(IndexPath(row: index, section: 2))
}
sidebar.items[2] = sorted.compactMap({ SidebarItem(name: $0, type: .Tag) })
insertRows(at: indexPaths, with: .fade)
}
public func delete(tags: [String]) {
guard let vc = viewController else { return }
var allTags = [String]()
if let project = vc.storage.searchQuery.projects.first {
allTags = project.getAllTags()
} else if let type = vc.storage.searchQuery.type {
var notes = [Note]()
switch type {
case .All:
notes = Storage.shared().noteList
break
case .Inbox:
notes = Storage.shared().noteList.filter({ $0.project.isDefault })
break
case .Todo:
notes = Storage.shared().noteList.filter({ $0.content.string.contains("- [ ] ") })
default:
break
}
for note in notes {
allTags.append(contentsOf: note.tags)
}
}
let currentTags = sidebar.items[2].compactMap({ $0.name })
var toRemovePaths = [IndexPath]()
var toRemoveTags = [String]()
for tag in tags {
if !allTags.contains(tag) {
if let row = currentTags.firstIndex(of: tag) {
toRemovePaths.append(IndexPath(row: row, section: 2))
toRemoveTags.append(tag)
}
}
}
sidebar.items[2].removeAll(where: { toRemoveTags.contains($0.name) })
deleteRows(at: toRemovePaths, with: .fade)
deSelectTagIfNonExist(tags: toRemoveTags)
}
private func createQueryWithoutTags() -> SearchQuery? {
guard let vc = viewController else { return nil }
let query = SearchQuery()
query.projects = vc.storage.searchQuery.projects
if let type = vc.storage.searchQuery.type {
query.type = type
if query.projects.first != nil && type == .Tag {
query.type = .Project
}
}
return query
}
private func deSelectTagIfNonExist(tags: [String]) {
guard let vc = viewController,
let tag = vc.storage.searchQuery.tags.first
else { return }
guard tags.contains(tag) else { return }
if let project = vc.storage.searchQuery.projects.first,
let index = getIndexPathBy(project: project)
{
tableView(self, didSelectRowAt: index)
return
}
if let type = vc.storage.searchQuery.type,
let index = getIndexPathBy(type: type) {
tableView(self, didSelectRowAt: index)
}
}
public func getSelectedSidebarItem() -> SidebarItem? {
guard let vc = viewController,
let project = vc.storage.searchQuery.projects.first
else { return nil }
let items = sidebar.items
for item in items {
for subItem in item {
if subItem.project == project {
return subItem
}
}
}
return nil
}
public func getIndexPathBy(project: Project) -> IndexPath? {
for (sectionId, section) in sidebar.items.enumerated() {
for (rowId, item) in section.enumerated() {
if item.project === project {
let indexPath = IndexPath(row: rowId, section: sectionId)
return indexPath
}
}
}
return nil
}
public func getIndexPathBy(tag: String) -> IndexPath? {
let tagsSection = SidebarSection.Tags.rawValue
for (rowId, item) in sidebar.items[tagsSection].enumerated() {
if item.name == tag {
let indexPath = IndexPath(row: rowId, section: tagsSection)
return indexPath
}
}
return nil
}
public func getIndexPathBy(type: SidebarItemType) -> IndexPath? {
let section = SidebarSection.System.rawValue
for (rowId, item) in sidebar.items[section].enumerated() {
if item.type == type {
let indexPath = IndexPath(row: rowId, section: section)
return indexPath
}
}
return nil
}
public func insertRows(projects: [Project]) {
guard sidebar.items.indices.contains(1) else { return }
var localItems = sidebar.items[1]
let existingProjects = localItems.compactMap { $0.project }
let toInsert = projects
.filter { !existingProjects.contains($0) && $0.settings.showInSidebar }
.sorted {
$0.label.localizedCaseInsensitiveCompare($1.label) == .orderedAscending
}
guard !toInsert.isEmpty else { return }
performBatchUpdates({
for project in toInsert {
let insertIndex = localItems.firstIndex {
$0.name.localizedCaseInsensitiveCompare(project.label) == .orderedDescending
} ?? localItems.count
let item = SidebarItem(
name: project.label,
project: project,
type: .Project
)
localItems.insert(item, at: insertIndex)
sidebar.items[1].insert(item, at: insertIndex)
insertRows(at: [IndexPath(row: insertIndex, section: 1)], with: .fade)
}
}, completion: { _ in
UIApplication.getVC().resizeSidebar()
})
}
public func removeRows(projects: [Project]) {
guard let vc = viewController else { return }
let toDelete: [Project] = projects.flatMap { [$0] + $0.getChildProjectsByURL() }
guard !toDelete.isEmpty else { return }
var deselectCurrent = false
performBatchUpdates({
var indexPathsToDelete = [IndexPath]()
for index in sidebar.items[1].indices.reversed() {
let item = sidebar.items[1][index]
guard let project = item.project else { continue }
if toDelete.contains(project) {
sidebar.items[1].remove(at: index)
indexPathsToDelete.append(IndexPath(row: index, section: 1))
if project == vc.storage.searchQuery.projects.first {
deselectCurrent = true
}
vc.storage.remove(project: project)
}
}
if !indexPathsToDelete.isEmpty {
deleteRows(at: indexPathsToDelete, with: .automatic)
}
}, completion: { _ in
if deselectCurrent {
vc.notesTable.notes.removeAll()
vc.notesTable.reloadData()
let indexPath = IndexPath(row: 0, section: 0)
self.tableView(self, didSelectRowAt: indexPath)
}
UIApplication.getVC().resizeSidebar()
})
}
public func select(project: Project) {
guard let indexPath = getIndexPathBy(project: project) else { return }
tableView(self, didSelectRowAt: indexPath)
}
public func select(tag: String) {
guard let indexPath = getIndexPathBy(tag: tag) else { return }
tableView(self, didSelectRowAt: indexPath)
}
public func remove(tag: String) {
guard let indexPath = getIndexPathBy(tag: tag) else { return }
sidebar.items[2].removeAll(where: { $0.name == tag})
deleteRows(at: [indexPath], with: .automatic)
selectCurrentProject()
}
public func reloadSidebar() {
sidebar = Sidebar()
reloadData()
var indexPath = IndexPath(row: 0, section: 0)
if
let projectURL = UserDefaultsManagement.lastProjectURL,
let project = Storage.shared().getProjectBy(url: projectURL),
let path = getIndexPathBy(project: project) {
indexPath = path
} else if let rowId = UserDefaultsManagement.lastSidebarItem {
indexPath = IndexPath(row: rowId, section: 0)
}
tableView(self, didSelectRowAt: indexPath)
viewController?.resizeSidebar(withAnimation: true)
}
public func reload(indexPath: IndexPath) {
// Important as cell resets after reloadRows
let currentPath = indexPathForSelectedRow
reloadRows(at: [indexPath], with: .automatic)
selectRow(at: currentPath, animated: false, scrollPosition: .none)
}
}
================================================
FILE: FSNotes iOS/ViewController+More.swift
================================================
//
// ViewController+More.swift
// FSNotes iOS
//
// Created by Олександр Глущенко on 10.01.2021.
// Copyright © 2021 Oleksandr Glushchenko. All rights reserved.
//
import Foundation
import UIKit
extension ViewController: UIDocumentPickerDelegate {
func makeSidebarSettingsMenu(for sidebarItem: SidebarItem) -> UIMenu? {
let project = sidebarItem.project
let handler: (_ action: UIAction) -> () = { action in
switch action.identifier.rawValue {
case "emptyBin":
self.emptyBin()
case "importNote":
self.importNote(selectedProject: project)
case "viewSettings":
self.openProjectSettings(sidebarItem: sidebarItem)
case "gitSettings":
self.openGitSettings(selectedProject: project)
case "bulkEditing":
self.bulkEditing()
case "createFolder":
self.createFolder(selectedProject: project)
case "removeFolder":
self.removeFolder(selectedProject: project)
case "renameFolder":
self.renameFolder(selectedProject: project)
case "removeTag":
self.removeTag(sidebarItem: sidebarItem)
case "renameTag":
self.renameTag(sidebarItem: sidebarItem)
case "openInFiles":
self.openInFiles(selectedProject: project)
case "lockFolder":
self.lockProject(selectedProject: project)
case "unlockFolder":
self.unlockProject(selectedProject: project)
case "decryptFolder":
self.decryptProject(selectedProject: project)
case "encryptFolder":
self.encryptProject(selectedProject: project)
case "gitAddCommitPush":
self.addCommitPush(selectedProject: project)
default:
break
}
}
// Build popovers
var popoverActions = [FolderPopoverActions]()
switch sidebarItem.type {
case .Inbox:
popoverActions = [.importNote, .settingsFolder, .createFolder, .multipleSelection, .openInFiles, .settingsRepository]
case .All, .Todo:
popoverActions = [.settingsFolder, .createFolder, .multipleSelection]
case .Trash:
popoverActions = [.settingsFolder, .multipleSelection, .openInFiles, .emptyBin]
case .Project:
popoverActions = [.importNote, .settingsFolder, .createFolder, .removeFolder, .renameFolder, .multipleSelection, .openInFiles, .settingsRepository, .encryptFolder]
case .Tag:
popoverActions = [.removeTag, .renameTag, .multipleSelection]
case .Untagged:
popoverActions = [.createFolder, .multipleSelection]
case .ProjectEncryptedLocked:
popoverActions = [.unLockFolder, .decryptFolder, .settingsFolder, .removeFolder, .renameFolder, .multipleSelection, .openInFiles, .settingsRepository]
case .ProjectEncryptedUnlocked:
popoverActions = [.lockFolder, .decryptFolder, .importNote, .settingsFolder, .createFolder, .removeFolder, .renameFolder, .multipleSelection, .openInFiles, .settingsRepository]
default: break
}
// Build actions
var actions = [UIAction]()
if popoverActions.contains(.removeFolder) {
let title = NSLocalizedString("Remove Folder", comment: "Main view popover table")
actions.append(UIAction(title: title, image: UIImage(systemName: "trash"), identifier: UIAction.Identifier("removeFolder"), attributes: .destructive, handler: handler))
}
if popoverActions.contains(.emptyBin) {
let title = NSLocalizedString("Empty Bin", comment: "Main view popover table")
actions.append(UIAction(title: title, image: UIImage(systemName: "xmark.circle"), identifier: UIAction.Identifier("emptyBin"), handler: handler))
}
if popoverActions.contains(.importNote) {
let title = NSLocalizedString("Import Notes", comment: "Main view popover table")
actions.append(UIAction(title: title, image: UIImage(systemName: "square.and.arrow.down"), identifier: UIAction.Identifier("importNote"), handler: handler))
}
if popoverActions.contains(.settingsFolder) {
let title = NSLocalizedString("View Settings", comment: "Main view popover table")
actions.append(UIAction(title: title, image: UIImage(systemName: "gearshape"), identifier: UIAction.Identifier("viewSettings"), handler: handler))
}
if popoverActions.contains(.settingsRepository) {
let title = NSLocalizedString("Git Settings", comment: "Main view popover table")
actions.append(UIAction(title: title, image: UIImage(named: "gitSettings"), identifier: UIAction.Identifier("gitSettings"), handler: handler))
if let project = sidebarItem.project, project.getGitProject() != nil {
let titleAddCommit = NSLocalizedString("Git Add/commit/push", comment: "Main view popover table")
actions.append(UIAction(title: titleAddCommit, image: UIImage(systemName: "plus.circle"), identifier: UIAction.Identifier("gitAddCommitPush"), handler: handler))
}
}
if popoverActions.contains(.multipleSelection) {
let title = NSLocalizedString("Select", comment: "Main view popover table")
actions.append(UIAction(title: title, image: UIImage(systemName: "checkmark.circle"), identifier: UIAction.Identifier("bulkEditing"), handler: handler))
}
if popoverActions.contains(.createFolder) {
let title = NSLocalizedString("Create Folder", comment: "Main view popover table")
actions.append(UIAction(title: title, image: UIImage(systemName: "folder.badge.plus"), identifier: UIAction.Identifier("createFolder"), handler: handler))
}
if popoverActions.contains(.renameFolder) {
let title = NSLocalizedString("Rename Folder", comment: "Main view popover table")
actions.append(UIAction(title: title, image: UIImage(systemName: "pencil.circle"), identifier: UIAction.Identifier("renameFolder"), handler: handler))
}
if popoverActions.contains(.removeTag) {
let title = NSLocalizedString("Remove Tag", comment: "Main view popover table")
actions.append(UIAction(title: title, image: UIImage(systemName: "tag.slash"), identifier: UIAction.Identifier("removeTag"), handler: handler))
}
if popoverActions.contains(.renameTag) {
let title = NSLocalizedString("Rename Tag", comment: "Main view popover table")
actions.append(UIAction(title: title, image: UIImage(systemName: "pencil.circle"), identifier: UIAction.Identifier("renameTag"), handler: handler))
}
if popoverActions.contains(.openInFiles) {
let title = NSLocalizedString("Open in Files.app", comment: "Main view popover table")
actions.append(UIAction(title: title, image: UIImage(systemName: "folder"), identifier: UIAction.Identifier("openInFiles"), handler: handler))
}
if popoverActions.contains(.lockFolder) {
let title = FolderPopoverActions.lockFolder.getDescription()
actions.append(UIAction(title: title, image: UIImage(systemName: "lock"), identifier: UIAction.Identifier("lockFolder"), handler: handler))
}
if popoverActions.contains(.unLockFolder) {
let title = FolderPopoverActions.unLockFolder.getDescription()
actions.append(UIAction(title: title, image: UIImage(systemName: "lock.open"), identifier: UIAction.Identifier("unlockFolder"), handler: handler))
}
if popoverActions.contains(.decryptFolder) {
let title = FolderPopoverActions.decryptFolder.getDescription()
actions.append(UIAction(title: title, image: UIImage(systemName: "lock.slash"), identifier: UIAction.Identifier("decryptFolder"), handler: handler))
}
if popoverActions.contains(.encryptFolder) {
let title = FolderPopoverActions.encryptFolder.getDescription()
actions.append(UIAction(title: title, image: UIImage(systemName: "lock"), identifier: UIAction.Identifier("encryptFolder"), handler: handler))
}
// Build title
var mainTitle = String()
switch sidebarItem.type {
case .Project:
if let project = sidebarItem.project {
mainTitle = project.getFullLabel()
}
case .Untagged:
mainTitle = NSLocalizedString("Untagged", comment: "")
default:
mainTitle = sidebarItem.getName()
}
return UIMenu(title: mainTitle, children: actions)
}
@IBAction public func openSidebarSettings() {
let mvc = UIApplication.getVC()
if notesTable.isEditing {
if let selectedRows = mvc.notesTable.selectedIndexPaths {
var notes = [Note]()
for indexPath in selectedRows {
if mvc.notesTable.notes.indices.contains(indexPath.row) {
let note = mvc.notesTable.notes[indexPath.row]
notes.append(note)
}
}
mvc.notesTable.selectedIndexPaths = nil
mvc.notesTable.actionsSheet(notes: notes, presentController: self)
} else {
mvc.notesTable.allowsMultipleSelectionDuringEditing = false
mvc.notesTable.setEditing(false, animated: true)
}
return
}
let sidebarItem = sidebarTableView.getSidebarItem()
let projectLabel = sidebarItem?.project?.getFullLabel() ?? String()
var type = sidebarItem?.type
var indexPath: IndexPath?
if let tag = Storage.shared().searchQuery.tags.first {
indexPath = sidebarTableView.getIndexPathBy(tag: tag)
}
if let path = indexPath, path.section == SidebarSection.Tags.rawValue {
type = .Tag
}
guard type != .Label else { return }
var actions = [FolderPopoverActions]()
switch type {
case .Inbox:
actions = [.importNote, .settingsFolder, .createFolder, .multipleSelection, .openInFiles, .settingsRepository]
case .All, .Todo:
actions = [.settingsFolder, .multipleSelection]
case .Trash:
actions = [.settingsFolder, .multipleSelection, .openInFiles, .emptyBin]
case .Project:
actions = [.importNote, .settingsFolder, .createFolder, .removeFolder, .renameFolder, .multipleSelection, .openInFiles, .settingsRepository, .encryptFolder]
case .Tag:
actions = [.removeTag, .renameTag, .multipleSelection]
case .Untagged:
actions = [.multipleSelection]
case .ProjectEncryptedLocked:
actions = [.unLockFolder, .decryptFolder, .importNote, .settingsFolder, .createFolder, .removeFolder, .renameFolder, .multipleSelection, .openInFiles, .settingsRepository]
case .ProjectEncryptedUnlocked:
actions = [.lockFolder, .decryptFolder, .importNote, .settingsFolder, .createFolder, .removeFolder, .renameFolder, .multipleSelection, .openInFiles, .settingsRepository]
default: break
}
var mainTitle = type != .Tag && type == .Project ? projectLabel : sidebarItem?.getName()
if type == .Untagged {
mainTitle = NSLocalizedString("Untagged", comment: "")
}
let actionSheet = UIAlertController(title: mainTitle, message: nil, preferredStyle: .actionSheet)
if actions.contains(.removeFolder) {
let title = NSLocalizedString("Remove Folder", comment: "Main view popover table")
let alertAction = UIAlertAction(title:title, style: .destructive, handler: { _ in
self.removeFolder(selectedProject: sidebarItem?.project)
})
alertAction.setValue(CATextLayerAlignmentMode.left, forKey: "titleTextAlignment")
if let image = UIImage(systemName: "trash")?.resize(maxWidthHeight: 23) {
alertAction.setValue(image, forKey: "image")
}
actionSheet.addAction(alertAction)
}
if actions.contains(.emptyBin) {
let title = NSLocalizedString("Empty Bin", comment: "Main view popover table")
let alertAction = UIAlertAction(title:title, style: .destructive, handler: { _ in
self.emptyBin()
})
alertAction.setValue(CATextLayerAlignmentMode.left, forKey: "titleTextAlignment")
if let image = UIImage(systemName: "xmark.circle")?.resize(maxWidthHeight: 23) {
alertAction.setValue(image, forKey: "image")
}
actionSheet.addAction(alertAction)
}
if actions.contains(.importNote) {
let title = NSLocalizedString("Import Notes", comment: "Main view popover table")
let importNote = UIAlertAction(title:title, style: .default, handler: { _ in
self.importNote(selectedProject: sidebarItem?.project)
})
importNote.setValue(CATextLayerAlignmentMode.left, forKey: "titleTextAlignment")
if let image = UIImage(systemName: "square.and.arrow.down")?.resize(maxWidthHeight: 23) {
importNote.setValue(image, forKey: "image")
}
actionSheet.addAction(importNote)
}
if actions.contains(.settingsFolder) {
let title = NSLocalizedString("View Settings", comment: "Main view popover table")
let settings = UIAlertAction(title:title, style: .default, handler: { _ in
self.openProjectSettings(sidebarItem: sidebarItem)
})
settings.setValue(CATextLayerAlignmentMode.left, forKey: "titleTextAlignment")
if let image = UIImage(systemName: "gearshape")?.resize(maxWidthHeight: 23) {
settings.setValue(image, forKey: "image")
}
actionSheet.addAction(settings)
}
if actions.contains(.settingsRepository) {
let title = NSLocalizedString("Git Settings", comment: "Main view popover table")
let alertAction = UIAlertAction(title:title, style: .default, handler: { _ in
self.openGitSettings(selectedProject: sidebarItem?.project)
})
alertAction.setValue(CATextLayerAlignmentMode.left, forKey: "titleTextAlignment")
if let image = UIImage(named: "gitSettings")?.resize(maxWidthHeight: 23) {
alertAction.setValue(image, forKey: "image")
}
actionSheet.addAction(alertAction)
}
if actions.contains(.multipleSelection) {
let title = NSLocalizedString("Select", comment: "Main view popover table")
let multipleSelection = UIAlertAction(title:title, style: .default, handler: { _ in
self.bulkEditing()
})
multipleSelection.setValue(CATextLayerAlignmentMode.left, forKey: "titleTextAlignment")
if let image = UIImage(systemName: "checkmark.circle")?.resize(maxWidthHeight: 23) {
multipleSelection.setValue(image, forKey: "image")
}
actionSheet.addAction(multipleSelection)
}
if actions.contains(.createFolder) {
let title = NSLocalizedString("Create Folder", comment: "Main view popover table")
let alertAction = UIAlertAction(title:title, style: .default, handler: { _ in
self.createFolder(selectedProject: sidebarItem?.project)
})
alertAction.setValue(CATextLayerAlignmentMode.left, forKey: "titleTextAlignment")
if let image = UIImage(systemName: "folder.badge.plus")?.resize(maxWidthHeight: 23) {
alertAction.setValue(image, forKey: "image")
}
actionSheet.addAction(alertAction)
}
if actions.contains(.renameFolder) {
let title = NSLocalizedString("Rename Folder", comment: "Main view popover table")
let alertAction = UIAlertAction(title:title, style: .default, handler: { _ in
self.renameFolder(selectedProject: sidebarItem?.project)
})
alertAction.setValue(CATextLayerAlignmentMode.left, forKey: "titleTextAlignment")
if let image = UIImage(systemName: "pencil.circle")?.resize(maxWidthHeight: 23) {
alertAction.setValue(image, forKey: "image")
}
actionSheet.addAction(alertAction)
}
if actions.contains(.removeTag) {
let title = NSLocalizedString("Remove Tag", comment: "Main view popover table")
let alertAction = UIAlertAction(title:title, style: .destructive, handler: { _ in
self.removeTag(sidebarItem: sidebarItem)
})
alertAction.setValue(CATextLayerAlignmentMode.left, forKey: "titleTextAlignment")
if let image = UIImage(systemName: "tag.slash")?.resize(maxWidthHeight: 23) {
alertAction.setValue(image, forKey: "image")
}
actionSheet.addAction(alertAction)
}
if actions.contains(.renameTag) {
let title = NSLocalizedString("Rename Tag", comment: "Main view popover table")
let alertAction = UIAlertAction(title:title, style: .default, handler: { _ in
self.renameTag(sidebarItem: sidebarItem)
})
alertAction.setValue(CATextLayerAlignmentMode.left, forKey: "titleTextAlignment")
if let image = UIImage(systemName: "pencil.circle")?.resize(maxWidthHeight: 23) {
alertAction.setValue(image, forKey: "image")
}
actionSheet.addAction(alertAction)
}
if actions.contains(.openInFiles) {
let title = NSLocalizedString("Open in Files.app", comment: "Main view popover table")
let alertAction = UIAlertAction(title:title, style: .default, handler: { _ in
self.openInFiles(selectedProject: sidebarItem?.project)
})
alertAction.setValue(CATextLayerAlignmentMode.left, forKey: "titleTextAlignment")
if let image = UIImage(systemName: "folder")?.resize(maxWidthHeight: 23) {
alertAction.setValue(image, forKey: "image")
}
actionSheet.addAction(alertAction)
}
if actions.contains(.lockFolder) {
let title = FolderPopoverActions.lockFolder.getDescription()
let alertAction = UIAlertAction(title:title, style: .default, handler: { _ in
self.lockProject(selectedProject: sidebarItem?.project)
})
alertAction.setValue(CATextLayerAlignmentMode.left, forKey: "titleTextAlignment")
if let image = UIImage(systemName: "lock")?.resize(maxWidthHeight: 23) {
alertAction.setValue(image, forKey: "image")
}
actionSheet.addAction(alertAction)
}
if actions.contains(.unLockFolder) {
let title = FolderPopoverActions.unLockFolder.getDescription()
let alertAction = UIAlertAction(title:title, style: .default, handler: { _ in
self.unlockProject(selectedProject: sidebarItem?.project)
})
alertAction.setValue(CATextLayerAlignmentMode.left, forKey: "titleTextAlignment")
if let image = UIImage(systemName: "lock.open")?.resize(maxWidthHeight: 23) {
alertAction.setValue(image, forKey: "image")
}
actionSheet.addAction(alertAction)
}
if actions.contains(.decryptFolder) {
let title = FolderPopoverActions.decryptFolder.getDescription()
let alertAction = UIAlertAction(title:title, style: .default, handler: { _ in
self.decryptProject(selectedProject: sidebarItem?.project)
})
alertAction.setValue(CATextLayerAlignmentMode.left, forKey: "titleTextAlignment")
if let image = UIImage(systemName: "lock.slash")?.resize(maxWidthHeight: 23) {
alertAction.setValue(image, forKey: "image")
}
actionSheet.addAction(alertAction)
}
if actions.contains(.encryptFolder) {
let title = FolderPopoverActions.encryptFolder.getDescription()
let alertAction = UIAlertAction(title:title, style: .default, handler: { _ in
self.encryptProject(selectedProject: sidebarItem?.project)
})
alertAction.setValue(CATextLayerAlignmentMode.left, forKey: "titleTextAlignment")
if let image = UIImage(systemName: "lock")?.resize(maxWidthHeight: 23) {
alertAction.setValue(image, forKey: "image")
}
actionSheet.addAction(alertAction)
}
let dismiss = UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .cancel, handler: nil)
actionSheet.addAction(dismiss)
actionSheet.popoverPresentationController?.sourceView = view
actionSheet.popoverPresentationController?.sourceRect = CGRect(x: view.bounds.size.width / 2.0, y: view.bounds.size.height, width: 2.0, height: 1.0)
present(actionSheet, animated: true, completion: nil)
}
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
guard let projectURL = selectedProject?.url else { return }
for url in urls {
let dstURL = projectURL.appendingPathComponent(url.lastPathComponent)
try? FileManager.default.copyItem(at: url, to: dstURL)
}
self.dismiss(animated: true, completion: nil)
}
private func importNote(selectedProject: Project?) {
self.selectedProject = selectedProject
let picker = UIDocumentPickerViewController(forOpeningContentTypes: [.item], asCopy: true)
picker.allowsMultipleSelection = true
picker.delegate = self
self.present(picker, animated: true, completion: nil)
}
public func openProjectSettings(sidebarItem: SidebarItem?) {
let vc = UIApplication.getVC()
let storage = Storage.shared()
// All projects
var currentProject = sidebarItem?.project
if currentProject == nil {
currentProject = storage.getCurrentProject()
}
// Virtual projects Notes and Todo
if sidebarItem?.type == .Todo || sidebarItem?.type == .All {
currentProject = sidebarItem?.project
}
guard let project = currentProject else { return }
let projectController = ProjectSettingsViewController(project: project, dismiss: true)
let controller = UINavigationController(rootViewController: projectController)
self.dismiss(animated: true, completion: nil)
vc.present(controller, animated: true, completion: nil)
}
@objc func bulkEditing() {
let mvc = UIApplication.getVC()
if !mvc.notesTable.isEditing {
mvc.notesTable.allowsMultipleSelectionDuringEditing = true
mvc.notesTable.setEditing(true, animated: true)
// load navbar
let cancelTitle = NSLocalizedString("Cancel", comment: "")
navigationItem.rightBarButtonItem = UIBarButtonItem(title: cancelTitle, style: .plain, target: self, action: #selector(cancel))
// load toolbar
let deleteImage = UIImage(systemName: "trash")
let calendarImage = UIImage(systemName: "calendar")
let duplicateImage = UIImage(systemName: "doc.on.doc")
let moveImage = UIImage(systemName: "move.3d")
if #available(iOS 14.0, *) {
var items = [UIBarButtonItem]()
items.append(UIBarButtonItem(image: deleteImage, style: .plain, target: self, action: #selector(removeNotes)))
items.append(UIBarButtonItem.flexibleSpace())
items.append(UIBarButtonItem(image: calendarImage, style: .plain, target: self, action: #selector(calendarNotes)))
items.append(UIBarButtonItem.flexibleSpace())
items.append(UIBarButtonItem(image: duplicateImage, style: .plain, target: self, action: #selector(duplicateNotes)))
items.append(UIBarButtonItem.flexibleSpace())
items.append(UIBarButtonItem(image: moveImage, style: .plain, target: self, action: #selector(moveNotes)))
toolbarItems = items
}
navigationController?.toolbar.tintColor = UIColor.mainTheme
navigationController?.setToolbarHidden(false, animated: true)
navigationController?.navigationBar.tintColor = UIColor.mainTheme
}
}
public func configureSidebarNavMenu() {
if let sidebarItem = UIApplication.getVC().lastSidebarItem {
configureNavMenu(for: sidebarItem)
}
}
@objc func removeNotes() {
let notes = notesTable.getSelectedNotes()
notesTable.removeAction(notes: notes)
notesTable.turnOffEditing()
configureSidebarNavMenu()
navigationController?.setToolbarHidden(true, animated: true)
configureToolbar()
}
@objc func calendarNotes() {
let notes = notesTable.getSelectedNotes()
notesTable.dateAction(notes: notes)
notesTable.turnOffEditing()
configureSidebarNavMenu()
configureToolbar()
navigationController?.setToolbarHidden(false, animated: true)
}
@objc func duplicateNotes() {
let notes = notesTable.getSelectedNotes()
notesTable.duplicateAction(notes: notes)
notesTable.turnOffEditing()
configureSidebarNavMenu()
configureToolbar()
navigationController?.setToolbarHidden(false, animated: true)
}
@objc func moveNotes() {
let notes = notesTable.getSelectedNotes()
notesTable.moveAction(notes: notes)
notesTable.turnOffEditing()
configureSidebarNavMenu()
configureToolbar()
navigationController?.setToolbarHidden(false, animated: true)
}
@objc func cancel() {
notesTable.turnOffEditing()
configureSidebarNavMenu()
configureToolbar()
navigationController?.setToolbarHidden(false, animated: true)
}
private func createFolder(selectedProject: Project?) {
guard var selectedProject = selectedProject else { return }
if selectedProject.isVirtual {
selectedProject = self.storage.getDefault()!
}
let mvc = UIApplication.getVC()
let alertController = UIAlertController(title: NSLocalizedString("Create folder:", comment: ""), message: nil, preferredStyle: .alert)
alertController.addTextField(configurationHandler: {
[] (textField: UITextField) in
textField.placeholder = NSLocalizedString("Enter folder name", comment: "")
})
let confirmAction = UIAlertAction(title: "OK", style: .default) { (_) in
guard let name = alertController.textFields?[0].text, name.count > 0 else {
return
}
let newDir = selectedProject.url.appendingPathComponent(name, isDirectory: true)
do {
try FileManager.default.createDirectory(at: newDir, withIntermediateDirectories: false, attributes: nil)
} catch {
print(error)
return
}
if let projects = Storage.shared().insert(url: newDir) {
OperationQueue.main.addOperation {
UIApplication.getVC().sidebarTableView.insertRows(projects: projects)
}
}
}
let title = NSLocalizedString("Cancel", comment: "")
let cancelAction = UIAlertAction(title: title, style: .cancel) { (_) in }
alertController.addAction(confirmAction)
alertController.addAction(cancelAction)
self.dismiss(animated: true, completion: nil)
mvc.present(alertController, animated: true) {
alertController.textFields![0].selectAll(nil)
}
}
private func removeFolder(selectedProject: Project?) {
guard let selectedProject = selectedProject else { return }
guard !selectedProject.isDefault else { return }
let mvc = UIApplication.getVC()
let alert = UIAlertController(
title: "Folder removing 🚨",
message: "Are you really want to remove \"\(selectedProject.label)\"? Folder content will be deleted, action can not be undone.",
preferredStyle: UIAlertController.Style.alert
)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action: UIAlertAction!) in
OperationQueue.main.addOperation {
mvc.sidebarTableView.removeRows(projects: [selectedProject])
if !selectedProject.isBookmark {
try? FileManager.default.removeItem(at: selectedProject.url)
}
Storage.shared().remove(project: selectedProject)
}
}))
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { (action: UIAlertAction!) in
}))
if selectedProject.isBookmark {
OperationQueue.main.addOperation {
let bookmark = SandboxBookmark.sharedInstance()
bookmark.remove(url: selectedProject.url)
mvc.sidebarTableView.removeRows(projects: [selectedProject])
}
} else {
mvc.present(alert, animated: true, completion: nil)
}
}
private func renameFolder(selectedProject: Project?) {
guard let selectedProject = selectedProject else { return }
let mvc = UIApplication.getVC()
let title = NSLocalizedString("Rename folder:", comment: "Popover table")
let alertController = UIAlertController(title: title, message: nil, preferredStyle: .alert)
alertController.addTextField(configurationHandler: {
[] (textField: UITextField) in
textField.placeholder = NSLocalizedString("Enter folder name", comment: "")
textField.text = selectedProject.url.lastPathComponent
})
let confirmAction = UIAlertAction(title: "OK", style: .default) { (_) in
OperationQueue.main.addOperation {
guard let name = alertController.textFields?[0].text, name.count > 0 else {
return
}
let newDir = selectedProject.url
.deletingLastPathComponent()
.appendingPathComponent(name, isDirectory: true)
do {
try FileManager.default.moveItem(at: selectedProject.url, to: newDir)
} catch {
print(error)
return
}
mvc.sidebarTableView.removeRows(projects: [selectedProject])
if let projects = self.storage.insert(url: newDir) {
mvc.sidebarTableView.insertRows(projects: projects)
if let first = projects.first {
mvc.sidebarTableView.select(project: first)
}
}
}
}
let cancel = NSLocalizedString("Cancel", comment: "")
let cancelAction = UIAlertAction(title: cancel, style: .cancel) { (_) in }
alertController.addAction(confirmAction)
alertController.addAction(cancelAction)
self.dismiss(animated: true, completion: nil)
mvc.present(alertController, animated: true) {
alertController.textFields![0].selectAll(nil)
}
}
private func removeTag(sidebarItem: SidebarItem?) {
let mvc = UIApplication.getVC()
guard let sidebarItem = sidebarItem, sidebarItem.type == .Tag else { return }
guard let selectedProject = mvc.storage.searchQuery.projects.first else { return }
let tag = sidebarItem.name
let notes =
mvc.storage.noteList
.filter({ $0.project == selectedProject })
.filter({ $0.tags.contains(tag) })
for note in notes {
note.replace(tag: "#\(tag)", with: "")
note.tags.removeAll(where: { $0 == tag })
}
mvc.sidebarTableView.remove(tag: tag)
self.dismiss(animated: true, completion: nil)
}
private func renameTag(sidebarItem: SidebarItem?) {
let mvc = UIApplication.getVC()
guard let sidebarItem = sidebarItem, sidebarItem.type == .Tag else { return }
guard let selectedProject = mvc.storage.searchQuery.projects.first else { return }
let tag = sidebarItem.name
let title = NSLocalizedString("Rename tag:", comment: "Popover table")
let alertController = UIAlertController(title: title, message: nil, preferredStyle: .alert)
alertController.addTextField(configurationHandler: {
[] (textField: UITextField) in
textField.placeholder = NSLocalizedString("Enter new tag name", comment: "")
textField.text = tag
})
let confirmAction = UIAlertAction(title: "OK", style: .default) { (_) in
guard var name = alertController.textFields?[0].text, name.count > 0 else {
return
}
name = name.withoutSpecialCharacters
guard name.count > 1 else { return }
let notes =
mvc.storage.noteList
.filter({ $0.project == selectedProject })
.filter({ $0.tags.contains(tag) })
for note in notes {
note.replace(tag: "#\(tag)", with: "#\(name)")
note.tags.removeAll(where: { $0 == tag })
_ = note.scanContentTags()
}
mvc.sidebarTableView.remove(tag: tag)
mvc.sidebarTableView.insert(tags: [name])
self.dismiss(animated: true, completion: nil)
}
let cancel = NSLocalizedString("Cancel", comment: "")
let cancelAction = UIAlertAction(title: cancel, style: .cancel) { (_) in }
alertController.addAction(confirmAction)
alertController.addAction(cancelAction)
self.dismiss(animated: true, completion: nil)
mvc.present(alertController, animated: true) {
alertController.textFields![0].selectAll(nil)
}
}
private func openInFiles(selectedProject: Project?) {
guard let selectedProject = selectedProject else { return }
guard let path = selectedProject.url.path.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlPathAllowed) else { return }
if let projectUrl = URL(string: "shareddocuments://" + path) {
UIApplication.shared.open(projectUrl, options: [:])
}
}
private func openGitSettings(selectedProject: Project?) {
guard let selectedProject = selectedProject else { return }
let projectController = AppDelegate.getGitVC(for: selectedProject)
let controller = UINavigationController(rootViewController: projectController)
self.dismiss(animated: true, completion: nil)
UIApplication.getVC().present(controller, animated: true, completion: nil)
}
private func emptyBin() {
let notes = storage.getAllTrash()
storage.removeNotes(notes: notes, fsRemove: true, completely: true) { [self]_ in
self.notesTable.removeRows(notes: notes)
}
}
@objc public func unlock() {
guard let project = sidebarTableView.getSelectedSidebarItem()?.project else { return }
unlockProject(selectedProject: project)
}
public func unlockProject(selectedProject: Project?, createNote: Bool = false) {
guard let selectedProject = selectedProject else { return }
getMasterPassword() { password in
let result = selectedProject.unlock(password: password)
DispatchQueue.main.async {
guard result.1.count > 0 || result.0.count == 0 else {
self.wrongPassAlert()
return
}
self.sidebarTableView.loadTags(notes: result.1)
self.disableLockedProject()
if let indexPath = self.sidebarTableView.getIndexPathBy(project: selectedProject),
let sidebarItem = self.sidebarTableView.getSidebarItem(project: selectedProject) {
sidebarItem.load(type: .ProjectEncryptedUnlocked)
self.sidebarTableView.reload(indexPath: indexPath)
self.sidebarTableView.select(project: selectedProject)
if createNote {
self.createNote()
}
}
self.reloadNotesTable()
self.configureSidebarNavMenu()
}
}
}
public func lockProject(selectedProject: Project?) {
guard let selectedProject = selectedProject else { return }
let locked = selectedProject.lock()
selectedProject.removeCache()
DispatchQueue.main.async {
self.sidebarTableView.loadTags(notes: locked)
self.enableLockedProject()
if let indexPath = self.sidebarTableView.getIndexPathBy(project: selectedProject),
let sidebarItem = self.sidebarTableView.getSidebarItem(project: selectedProject) {
sidebarItem.load(type: .ProjectEncryptedLocked)
self.sidebarTableView.reload(indexPath: indexPath)
self.sidebarTableView.select(project: selectedProject)
}
self.reloadNotesTable()
self.configureSidebarNavMenu()
}
}
public func encryptProject(selectedProject: Project?) {
guard let selectedProject = selectedProject else { return }
getMasterPassword() { password in
let encrypted = selectedProject.encrypt(password: password)
selectedProject.removeCache()
DispatchQueue.main.async {
self.sidebarTableView.loadTags(notes: encrypted)
self.enableLockedProject()
if let indexPath = self.sidebarTableView.getIndexPathBy(project: selectedProject),
let sidebarItem = self.sidebarTableView.getSidebarItem(project: selectedProject) {
sidebarItem.load(type: .ProjectEncryptedLocked)
self.sidebarTableView.reload(indexPath: indexPath)
self.sidebarTableView.select(project: selectedProject)
}
self.reloadNotesTable()
self.configureSidebarNavMenu()
}
}
}
public func addCommitPush(selectedProject: Project?) {
guard let selectedProject = selectedProject?.getGitProject() else { return }
notesTable.saveRevisionAction(project: selectedProject)
}
public func decryptProject(selectedProject: Project?) {
guard let selectedProject = selectedProject else { return }
getMasterPassword() { password in
let notes = selectedProject.storage.getNotesBy(project: selectedProject)
let decrypted = selectedProject.decrypt(password: password)
DispatchQueue.main.async {
guard decrypted.count > 0 || notes.count == 0 else {
self.wrongPassAlert()
return
}
self.sidebarTableView.loadTags(notes: decrypted)
self.disableLockedProject()
if let indexPath = self.sidebarTableView.getIndexPathBy(project: selectedProject),
let sidebarItem = self.sidebarTableView.getSidebarItem(project: selectedProject) {
sidebarItem.load(type: .Project)
self.sidebarTableView.reload(indexPath: indexPath)
self.sidebarTableView.select(project: selectedProject)
}
self.reloadNotesTable()
self.configureSidebarNavMenu()
}
}
}
private func wrongPassAlert() {
let message = NSLocalizedString("Wrong password", comment: "")
let alertController = UIAlertController(title: message, message: nil, preferredStyle: .alert)
let okAction = UIAlertAction(title: "OK", style: .cancel) { (_) in }
alertController.addAction(okAction)
self.present(alertController, animated: true, completion: nil)
}
}
================================================
FILE: FSNotes iOS/ViewController.swift
================================================
//
// ViewController.swift
// FSNotes iOS
//
// Created by Oleksandr Glushchenko on 1/29/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import UIKit
import LocalAuthentication
import WebKit
import AudioToolbox
import CoreSpotlight
class ViewController: UIViewController, UISearchBarDelegate, UIGestureRecognizerDelegate, UISearchControllerDelegate {
@IBOutlet weak var sidebarTableBottomConstraint: NSLayoutConstraint!
@IBOutlet weak var notesTableBottomContraint: NSLayoutConstraint!
@IBOutlet weak var notesTableLeadingConstraint: NSLayoutConstraint!
@IBOutlet weak var sidebarTableLeadingConstraint: NSLayoutConstraint!
@IBOutlet weak var sidebarTableWidth: NSLayoutConstraint!
@IBOutlet weak var notesTable: NotesTableView!
@IBOutlet weak var sidebarTableView: SidebarTableView!
@IBOutlet weak var leftPreSafeArea: UIView!
@IBOutlet weak var rightPreSafeArea: UIView!
@IBOutlet weak var lockedProject: UIImageView!
private var newsPopup: MPreviewView?
private var newsOverlay: UIView?
public var indicator: UIActivityIndicatorView?
public var storage = Storage.shared()
public var cloudDriveManager: CloudDriveManager?
private let searchQueue = OperationQueue()
private let metadataQueue = OperationQueue()
public let gitQueue = OperationQueue()
public let gitQueueState = OperationQueue()
private var delayedInsert: Note?
private var maxSidebarWidth = CGFloat(0)
private var accessTime = DispatchTime.now()
public var isActiveTableUpdating = false
private var queryDidFinishGatheringObserver : Any?
private var isBackground: Bool = false
public var shouldReturnToControllerIndex = false
// Swipe animation from handleSidebarSwipe
private var sidebarWidth: CGFloat = 0
private var isLandscape: Bool?
public var restoreFindID: String?
public var isLoadedDB: Bool = false
public var isLoadedSidebar: Bool = false
public var folderCapacity: String?
public var currentFolder: String?
lazy var searchBar = UISearchBar(frame: CGRect.zero)
// Pass for access from CloudDriveManager
public var editorViewController: EditorViewController?
private var gitClean: Bool = false
private var gitPullTimer: Timer?
private var searchFocus: Bool = false
private var searchString: String? = nil
// Project for import picker
public var selectedProject: Project?
public var initialLoadingState = false
override func viewWillAppear(_ animated: Bool) {
navigationController?.navigationBar.prefersLargeTitles = false
super.viewWillAppear(animated)
navigationItem.searchController = nil
}
override func viewDidAppear(_ animated: Bool) {
if nil == Storage.shared().getRoot() {
let alert = UIAlertController(title: "Storage not found", message: "Please enable iCloud Drive for this app and try again!", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .destructive, handler: { action in
exit(0)
}))
self.present(alert, animated: true, completion: nil)
}
// Clean preview after previous loading
UIApplication.getEVC().getPreviewView()?.clean()
// If return from editor
UIApplication.getEVC().userActivity?.invalidate()
loadPreSafeArea()
if let sidebarItem = UIApplication.getVC().lastSidebarItem {
configureNavMenu(for: sidebarItem)
}
if searchFocus {
disableSearchFocus()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1, execute: {
if let text = self.searchString {
self.navigationItem.searchController?.searchBar.text = text
}
self.navigationItem.searchController?.searchBar.becomeFirstResponder()
})
} else if !isLoadedSidebar {
notesTable.showLoader()
}
super.viewDidAppear(animated)
configureSearchController()
}
override func viewDidLoad() {
startCloudDriveSyncEngine()
configureUI()
configureNotifications()
configureGestures()
gitQueue.qualityOfService = .userInteractive
gitQueue.maxConcurrentOperationCount = 1
gitQueue.isSuspended = true
gitQueueState.qualityOfService = .background
gitQueueState.maxConcurrentOperationCount = 1
scheduledGitPull()
disableLockedProject()
loadSidebar()
loadNotches()
loadPreSafeArea()
if !initialLoadingState {
configureSearchController()
initialLoadingState = true
loadNews()
if let sceneDelegate = UIApplication.getSceneDelegate(),
let shortcut = sceneDelegate.launchedShortcutItem {
handleShortCutItem(shortcut)
sceneDelegate.launchedShortcutItem = nil
} else {
self.restoreLastController()
}
DispatchQueue.global(qos: .userInteractive).async {
self.loadDB()
}
}
super.viewDidLoad()
configureToolbar()
isLandscape = UIDevice.current.orientation.isLandscape
}
@objc public func didBecomeActive() {
DispatchQueue.global(qos: .background).async {
self.checkExternal()
}
addPullTask()
}
public func scheduledGitPull() {
// Scheduling timer to Call the function "updateCounting" with the interval of 1 seconds
gitPullTimer?.invalidate()
gitPullTimer = Timer.scheduledTimer(timeInterval: 30, target: self, selector: #selector(self.addPullTask), userInfo: nil, repeats: true)
}
public func startCloudDriveSyncEngine(completion: (() -> ())? = nil) {
guard UserDefaultsManagement.iCloudDrive else { return }
cloudDriveManager = CloudDriveManager(delegate: self, storage: self.storage)
cloudDriveManager?.metadataQuery.disableUpdates()
if let cdm = self.cloudDriveManager {
self.queryDidFinishGatheringObserver = NotificationCenter.default.addObserver(forName: NSNotification.Name.NSMetadataQueryDidFinishGathering, object: cdm.metadataQuery, queue: self.metadataQueue) { notification in
cdm.queryDidFinishGathering(notification: (notification as NSNotification))
completion?()
NotificationCenter.default.removeObserver(self.queryDidFinishGatheringObserver as Any, name: NSNotification.Name.NSMetadataQueryDidFinishGathering, object: nil)
NotificationCenter.default.addObserver(forName: NSNotification.Name.NSMetadataQueryDidUpdate, object: cdm.metadataQuery, queue: self.metadataQueue) { notification in
UIApplication.shared.runInBackground({
cdm.handleMetadataQueryUpdates(notification: notification as NSNotification)
})
}
}
self.cloudDriveManager?.metadataQuery.start()
}
}
public func stopCloudDriveSyncEngine() {
self.cloudDriveManager?.metadataQuery.stop()
}
public func configureUI() {
//UINavigationBar.appearance().isTranslucent = true
self.metadataQueue.qualityOfService = .userInteractive
self.indicator = UIActivityIndicatorView(style: UIActivityIndicatorView.Style.large)
navigationItem.leftBarButtonItems = [
UIBarButtonItem(systemImageName: "sidebar.left", target: self, selector: #selector(openSidebar)),
UIBarButtonItem(systemImageName: "gear", target: self, selector: #selector(openSettings))
]
setNavTitle(folder: NSLocalizedString("Inbox", comment: ""))
sidebarTableView.backgroundColor = UIColor.sidebar
sidebarTableView.dropDelegate = sidebarTableView
if #available(iOS 15.0, *) {
sidebarTableView.sectionHeaderTopPadding = 0
}
notesTable.viewDelegate = self
notesTable.dragInteractionEnabled = true
notesTable.dragDelegate = notesTable
notesTable.keyboardDismissMode = .interactive
notesTable.contentInsetAdjustmentBehavior = .never
notesTable.alwaysBounceVertical = true
notesTable.dataSource = notesTable
notesTable.delegate = notesTable
notesTable.layer.zPosition = 100
notesTable.rowHeight = UITableView.automaticDimension
notesTable.estimatedRowHeight = 160
notesTable.tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: CGFloat.leastNormalMagnitude))
}
public var lastSidebarItem: SidebarItem? = nil
public func configureNavMenu(for sidebarItem: SidebarItem) {
lastSidebarItem = sidebarItem
if let menu = makeSidebarSettingsMenu(for: sidebarItem) {
navigationItem.rightBarButtonItem = UIBarButtonItem(systemImageName: "ellipsis.circle", menu: menu)
}
}
public func setNavTitle(folder: String? = nil, qty: String? = nil) {
if let folder = folder {
currentFolder = folder
}
if let qty = qty {
folderCapacity = qty
}
let folder = currentFolder ?? ""
var qty = folderCapacity ?? "∞"
if let item = sidebarTableView.getSidebarItem()?.project, item.isCleanGit {
qty += " | git ✓"
}
navigationItem.title = folder
if #available(iOS 26.0, *) {
navigationItem.subtitle = qty
}
}
public func configureNotifications() {
NotificationCenter.default.addObserver(self,
selector: #selector(ubiquitousKeyValueStoreDidChange(_:)),
name: NSUbiquitousKeyValueStore.didChangeExternallyNotification,
object: NSUbiquitousKeyValueStore.default)
if NSUbiquitousKeyValueStore.default.synchronize() == false {
fatalError("This app was not built with the proper entitlement requests.")
}
NSUbiquitousKeyValueStore.default.synchronize()
NotificationCenter.default.addObserver(self, selector: #selector(preferredContentSizeChanged), name: UIContentSizeCategory.didChangeNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(rotated), name: UIDevice.orientationDidChangeNotification, object: nil)
NotificationCenter.default.addObserver(self, selector:#selector(willExitForeground), name: UIApplication.willEnterForegroundNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(didBecomeActive), name: UIApplication.didBecomeActiveNotification, object: nil)
}
public func configureGestures() {
let swipe = UIPanGestureRecognizer(target: self, action: #selector(handleSidebarSwipe))
swipe.minimumNumberOfTouches = 1
swipe.delegate = self
view.addGestureRecognizer(swipe)
let longTapOnSidebar = UILongPressGestureRecognizer(target: self, action: #selector(sidebarLongPress))
longTapOnSidebar.minimumPressDuration = 0.5
view.addGestureRecognizer(longTapOnSidebar)
}
public func configureSearchController() {
let text = navigationItem.searchController?.searchBar.text
let searchController = UISearchController(searchResultsController: nil)
searchController.hidesNavigationBarDuringPresentation = false
searchController.searchBar.delegate = self
searchController.searchBar.searchBarStyle = .minimal
searchController.searchBar.placeholder = NSLocalizedString("Search or create", comment: "")
searchController.searchBar.returnKeyType = .done
if #available(iOS 26.0, *) {
searchController.searchBar.showsCancelButton = true
} else {
searchController.searchBar.showsCancelButton = false
}
searchController.searchBar.autocapitalizationType = .none
searchController.searchBar.keyboardAppearance = traitCollection.userInterfaceStyle == .dark ? .dark : .default
if let text = text {
searchController.searchBar.text = text
}
navigationItem.searchController = searchController
navigationController?.setToolbarHidden(false, animated: true)
}
public func configureToolbar() {
var items = [UIBarButtonItem]()
if #available(iOS 26.0, *) {
items.append(navigationItem.searchBarPlacementBarButtonItem)
}
items.append(.flexibleSpace())
items.append(
Buttons.getNewNote(
target: self,
selector: #selector(newButtonAction)
)
)
if needsRightPadding() {
let rightPadding = UIBarButtonItem(
barButtonSystemItem: .fixedSpace,
target: nil,
action: nil
)
rightPadding.width = 30
items.append(rightPadding)
}
toolbarItems = items
}
private func needsRightPadding() -> Bool {
if #available(iOS 26.0, *) { return false }
return true
}
public func enableSearchFocus(string: String? = nil) {
searchFocus = true
searchString = string
}
public func disableSearchFocus() {
searchFocus = false
}
public func handleShortCutItem(_ shortcutItem: UIApplicationShortcutItem) {
guard ShortcutIdentifier(fullType: shortcutItem.type) != nil else { return }
guard let shortCutType = shortcutItem.type as String? else { return }
switch shortCutType {
case ShortcutIdentifier.makeNew.type:
self.createNote()
break
case ShortcutIdentifier.clipboard.type:
self.createNote(pasteboard: true)
break
case ShortcutIdentifier.search.type:
self.loadViewIfNeeded()
self.enableSearchFocus()
self.popViewController()
self.loadSearchController()
break
default:
break
}
}
@IBAction public func openSidebar() {
if UserDefaultsManagement.sidebarIsOpened {
hideSidebar()
} else {
showSidebar()
}
}
@IBAction public func sidebarLongPress(gesture: UILongPressGestureRecognizer) {
guard UserDefaultsManagement.sidebarIsOpened else { return }
let p = gesture.location(in: self.sidebarTableView)
guard p.x < maxSidebarWidth, let indexPath = self.sidebarTableView.indexPathForRow(at: p) else { return }
if gesture.state != .ended {
sidebarTableView.tableView(sidebarTableView, didSelectRowAt: indexPath)
openSidebarSettings()
}
gesture.state = .ended
}
public func loadSidebar() {
sidebarTableView.dataSource = self.sidebarTableView
sidebarTableView.delegate = self.sidebarTableView
sidebarTableView.viewController = self
maxSidebarWidth = self.calculateLabelMaxWidth()
lockedProject.layer.zPosition = 1001
lockedProject.isUserInteractionEnabled = true
let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(unlock))
lockedProject.addGestureRecognizer(tapRecognizer)
initSidebar()
if UserDefaultsManagement.sidebarIsOpened {
resizeSidebar()
}
}
public func loadDB() {
let storage = self.storage
let dirsLoading = Date()
storage.loadNonSystemProject()
storage.loadProjectRelations()
print("1. Loaded non system projects and relations in \(dirsLoading.timeIntervalSinceNow * -1) seconds")
let notesLoadingPoint = Date()
let projects = storage.getProjects()
for project in projects {
// print("Reading project: \(project.label) (\(project.url))")
_ = project.loadNotes()
}
print("2. Notes loading finished in \(notesLoadingPoint.timeIntervalSinceNow * -1) seconds")
OperationQueue.main.addOperation {
self.importSavedInSharedExtension()
self.sidebarTableView.reloadSidebar()
DispatchQueue.global(qos: .userInitiated).async {
let diffLoading = Date()
for project in storage.getProjects() {
let changes = project.checkNotesCacheDiff()
self.notesTable.doVisualChanges(results: changes)
}
print("3. Notes diff loading finished in \(diffLoading.timeIntervalSinceNow * -1) seconds")
// find://
if let restore = self.restoreFindID {
self.restoreFindID = nil
if let note = Storage.shared().getBy(title: restore) {
OperationQueue.main.addOperation {
self.notesTable.hideLoader()
UIApplication.getEVC().load(note: note)
}
}
}
// Load notes content
let notesFullLoading = Date()
self.storage.loadNotesContent()
print("4. Full notes loading in \(notesFullLoading.timeIntervalSinceNow * -1) seconds")
let spotlightPoint = Date()
self.reIndexSpotlight()
print("5. Spotlight indexation finished in \(spotlightPoint.timeIntervalSinceNow * -1) seconds")
// enable iCloud Drive updates after projects structure formalized
self.cloudDriveManager?.metadataQuery.enableUpdates()
self.isLoadedDB = true
self.gitQueue.isSuspended = false
}
}
}
private func reIndexSpotlight() {
CSSearchableIndex.default().deleteAllSearchableItems { (error) in
if let error = error {
print("Spotlight \(error)")
}
}
var spotlightItems = [CSSearchableItem]()
for note in storage.noteList {
if note.project.isTrash || !note.project.settings.showInCommon {
continue
}
let attributed = CSSearchableItemAttributeSet(itemContentType: "Text")
attributed.title = note.title
attributed.contentDescription = note.content.string
attributed.lastUsedDate = note.modifiedLocalAt
let item = CSSearchableItem(uniqueIdentifier: note.url.path, domainIdentifier: "Notes", attributeSet: attributed)
spotlightItems.append(item)
}
CSSearchableIndex.default().indexSearchableItems(spotlightItems) { (error) in
if let error = error {
print("Spotlight \(error)")
}
}
}
public func updateSpotlightIndex(notes: [Note]) {
var items = [CSSearchableItem]()
for note in notes {
let attributed = CSSearchableItemAttributeSet(itemContentType: "Text")
attributed.title = note.title
attributed.contentDescription = note.content.string
attributed.lastUsedDate = note.modifiedLocalAt
let item = CSSearchableItem(uniqueIdentifier: note.url.path, domainIdentifier: "Notes", attributeSet: attributed)
items.append(item)
}
CSSearchableIndex.default().indexSearchableItems(items, completionHandler: nil)
}
public func removeSpotlightIndex(notes: [Note]) {
var idents = [String]()
for note in notes {
idents.append(note.url.path)
}
CSSearchableIndex.default().deleteSearchableItems(withDomainIdentifiers: idents, completionHandler: nil)
}
private func loadNews() {
guard storage.isReadedNewsOutdated(),
let newsURL = storage.getNews(),
let defaultProject = storage.getDefault() else { return }
let isLandscape = UIDevice.current.orientation.isLandscape
newsPopup?.removeFromSuperview()
newsOverlay?.removeFromSuperview()
let screeenWidth = UIScreen.main.bounds.width
let screeenHeight = UIScreen.main.bounds.height
let overlay = UIView(frame: CGRect(x: 0, y: 0, width: screeenWidth, height: screeenHeight))
overlay.layer.zPosition = 104
overlay.backgroundColor = UIColor(red: 0/255, green: 0/255, blue: 0/255, alpha: 0.5)
UIApplication.shared.windows.first(where: { $0.isKeyWindow })?.addSubview(overlay)
self.newsOverlay = overlay
var width = UIScreen.main.bounds.width - 20
if isLandscape {
width = UIScreen.main.bounds.width * 0.75
}
let height = screeenHeight * 0.75
let note = Note(url: newsURL, with: defaultProject)
note.load()
let frame = CGRect(
x: (screeenWidth - width) / 2,
y: (screeenHeight - height) / 2,
width: width,
height: height
)
let news = MPreviewView(frame: frame, note: note, closure: {})
news.layer.zPosition = 105
news.backgroundColor = UIColor.white
news.layer.cornerRadius = 5
news.layer.masksToBounds = true
news.layer.borderWidth = 1
news.layer.borderColor = UIColor.gray.cgColor
if #available(iOS 15.0, *) {
var config = UIButton.Configuration.plain()
config.image = UIImage(systemName: "xmark.circle.fill")
config.preferredSymbolConfigurationForImage = .init(pointSize: 25)
config.baseForegroundColor = UIColor.mainTheme
let closeButton = UIButton(frame: CGRect(x: width - 5 - 60, y: 5, width: 60, height: 60))
closeButton.configuration = config
closeButton.addTarget(self, action: #selector(closeNews), for: .touchDown)
news.addSubview(closeButton)
}
UIApplication.shared.windows.first(where: { $0.isKeyWindow })?.addSubview(news)
self.newsPopup = news
}
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
if let recognizer = gestureRecognizer as? UIPanGestureRecognizer {
if recognizer.translation(in: self.view).x > 0 && !UserDefaultsManagement.sidebarIsOpened
|| recognizer.translation(in: self.view).x < 0 &&
UserDefaultsManagement.sidebarIsOpened {
return true
}
}
return false
}
public func getLeftInset() -> CGFloat {
return view.safeAreaInsets.left
}
public func getRightInset() -> CGFloat {
return view.safeAreaInsets.right
}
public func loadNotches() {
rightPreSafeArea.backgroundColor = .whiteBlack
}
public func loadPreSafeArea() {
if UserDefaultsManagement.sidebarIsOpened {
// blue/black pre safe area
leftPreSafeArea.backgroundColor = UIColor.sidebar
rightPreSafeArea.backgroundColor = .whiteBlack
} else {
leftPreSafeArea.backgroundColor = .whiteBlack
rightPreSafeArea.backgroundColor = .whiteBlack
}
}
@objc public func openSettings() {
navigationController?.interactivePopGestureRecognizer?.delegate = nil
navigationController?.pushViewController(SettingsViewController(), animated: true)
}
@objc func ubiquitousKeyValueStoreDidChange(_ notification: NSNotification) {
if let keys = notification.userInfo?[NSUbiquitousKeyValueStoreChangedKeysKey] as? [String] {
for key in keys {
if key == "co.fluder.fsnotes.pins.shared" {
let result = storage.restoreCloudPins()
DispatchQueue.main.async {
if let added = result.added {
self.notesTable.addPins(notes: added)
}
if let removed = result.removed {
self.notesTable.removePins(notes: removed)
}
}
}
if key.startsWith(string: "es.fsnot.project-settings") {
let settingsKey = key.replacingOccurrences(of: "es.fsnot.project-settings", with: "")
if let project = storage.getProjectBy(settingsKey: settingsKey) {
project.reloadSettings()
DispatchQueue.main.async {
if let result = project.loadWebAPI() {
self.notesTable.reloadRows(notes: result.0 + result.1)
}
}
}
}
}
}
}
@objc func toggleSearch(refreshControl: UIRefreshControl) {
if storage.hasOrigins() {
addPullTask(force: true)
} else {
toggleSearchView()
}
refreshControl.endRefreshing()
}
@objc func addPullTask(force: Bool = false) {
guard storage.hasOrigins() else { return }
guard UIApplication.getVC().gitQueue.operationCount == 0 else {
print("Pull skipped")
return
}
let viewController = UIApplication.getVC()
viewController.gitQueue.addOperation({
Storage.shared().pullAll(force: force)
if !UserDefaultsManagement.iCloudDrive {
self.checkNew()
}
// if viewController.gitQueueState.operationCount == 0 {
// viewController.gitQueueState.addOperation {
// Storage.shared().checkGitState()
// DispatchQueue.main.async {
// self.updateNotesCounter()
// }
// }
// }
})
}
public func checkNew() {
if let projects = Storage.shared().getGitProjects() {
for project in projects {
if let childProjects = project.getAllChild() {
for childProject in childProjects {
let changes = childProject.checkNotesCacheDiff(isGit: true)
self.notesTable.doVisualChanges(results: changes)
}
}
let changes = project.checkNotesCacheDiff(isGit: true)
self.notesTable.doVisualChanges(results: changes)
}
}
}
public func checkExternal() {
let projects = Storage.shared().projects.filter({ $0.isBookmark })
guard projects.count > 0 else { return }
var remove = [Note]()
var insert = [Note]()
var reload = [Note]()
for project in projects {
if let childProjects = project.getAllChild() {
for childProject in childProjects {
let changes = childProject.checkFSAndMemoryDiff()
remove += changes.0
insert += changes.1
reload += changes.2
}
}
let changes = project.checkFSAndMemoryDiff()
remove += changes.0
insert += changes.1
reload += changes.2
}
for note in insert {
note.loadPreviewInfo()
}
for note in reload {
note.invalidateCache()
note.loadPreviewInfo()
}
self.notesTable.doVisualChanges(results: (remove, insert, reload))
}
public func loadSearchController(query: String? = nil) {
if let query = query {
navigationItem.searchController?.searchBar.text = query
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
self.navigationItem.searchController?.searchBar.becomeFirstResponder()
}
}
private func toggleSearchView() {
loadSearchController()
sidebarTableView.deselectAll()
reloadNotesTable()
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
buildSearchQuery()
reloadNotesTable()
}
func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
if #available(iOS 26.0, *) {
if let sc = navigationItem.searchController {
sc.isActive = false
sc.searchBar.resignFirstResponder()
}
} else {
configureSearchController()
}
}
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
notesTable.setContentOffset(CGPoint(x: 0, y: -44), animated: true)
disableLockedProject()
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
let content = searchBar.text
searchBar.text = ""
buildSearchQuery()
reloadNotesTable()
self.createNote(content: content)
}
public func configureIndicator(indicator: UIActivityIndicatorView, view: UIView) {
indicator.frame = CGRect(x: 0.0, y: 0.0, width: 50.0, height: 50.0)
indicator.center = view.center
indicator.layer.cornerRadius = 5
indicator.layer.borderWidth = 1
indicator.layer.borderColor = UIColor.lightGray.cgColor
view.addSubview(indicator)
indicator.bringSubviewToFront(view)
}
public func reloadNotesTable(completion: (() -> ())? = nil) {
isActiveTableUpdating = true
searchQueue.cancelAllOperations()
setNavTitle(qty: "∞")
searchQueue.cancelAllOperations()
let operation = BlockOperation()
operation.addExecutionBlock { [weak self] in
guard let self = self else {
completion?()
return
}
self.accessTime = DispatchTime.now()
let source = self.storage.noteList
var notes = [Note]()
for note in source {
if operation.isCancelled {
break
}
if Storage.shared().searchQuery.isFit(note: note) {
notes.append(note)
}
}
if let project = Storage.shared().searchQuery.projects.first, project.isLocked() {
notes.removeAll()
}
var modifiedNotesList = [Note]()
if !notes.isEmpty {
modifiedNotesList = self.storage.sortNotes(noteList: notes)
}
if operation.isCancelled {
completion?()
return
}
DispatchQueue.main.async {
self.setNavTitle(qty: String(notes.count))
if DispatchTime.now() < self.accessTime {
completion?()
return
}
self.notesTable.notes = modifiedNotesList
self.notesTable.reloadData()
if let note = self.delayedInsert {
self.notesTable.insertRows(notes: [note])
self.delayedInsert = nil
}
self.isActiveTableUpdating = false
completion?()
}
}
self.searchQueue.addOperation(operation)
}
public func updateNotesCounter() {
DispatchQueue.main.async {
self.setNavTitle(qty: String(self.notesTable.notes.count))
}
}
public func isNoteInsertionAllowed() -> Bool {
if let searchBar = getSearchBar() {
return !searchBar.isFirstResponder
}
return true
}
public func getSearchBar() -> UISearchBar? {
return navigationItem.searchController?.searchBar
}
@objc func newButtonAction() {
if let project = sidebarTableView.getSidebarProjects()?.first, project.isEncrypted, project.password == nil {
unlockProject(selectedProject: project, createNote: true)
return
}
createNote(content: nil)
}
@objc public func closeNews() {
UIImpactFeedbackGenerator(style: .medium).impactOccurred()
newsPopup?.removeFromSuperview()
newsOverlay?.removeFromSuperview()
// mark as read
UserDefaultsManagement.lastNews = storage.getNewsDate()
}
public func createNote(content: String? = nil, pasteboard: Bool = false) {
var currentProject: Project
if let project = storage.getProjects().first {
currentProject = project
} else {
return
}
if let item = self.sidebarTableView.getSidebarItem(),
let project = item.project,
!project.isTrash,
!project.isVirtual {
currentProject = project
}
let note = Note(name: "", project: currentProject)
if let content = content {
note.content = NSMutableAttributedString(string: content)
}
var selectedRange: NSRange?
if pasteboard {
if let image = UIPasteboard.general.image,
let data = image.jpegData(compressionQuality: 1),
let imagePath = ImagesProcessor.writeFile(data: data, note: note)
{
let string = ")\n\n"
note.content = NSMutableAttributedString(string: string)
selectedRange = NSRange(location: string.count, length: 0)
} else if let content = UIPasteboard.general.string {
note.content = NSMutableAttributedString(string: content)
selectedRange = NSRange(location: content.count, length: 0)
}
}
if note.save() {
Storage.shared().add(note)
}
let evc = UIApplication.getEVC()
evc.note = note
evc.fill(note: note, selectedRange: selectedRange)
openEditorViewController()
if self.isActiveTableUpdating {
self.delayedInsert = note
} else {
notesTable.insertRows(notes: [note])
notesTable.scrollTo(note: note)
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
let evc = UIApplication.getEVC()
if note.previewState {
evc.togglePreview()
}
evc.editArea.becomeFirstResponder()
if let password = note.project.password {
if note.encrypt(password: password) {
if note.unLock(password: password) {
note.password = password
}
}
}
}
}
public func openEditorViewController() {
navigationController?.interactivePopGestureRecognizer?.delegate = nil
if let controllers = navigationController?.viewControllers {
for controller in controllers {
if let _ = controller as? EditorViewController {
return
}
}
}
let evc = UIApplication.getEVC()
editorViewController = evc
navigationController?.pushViewController(evc, animated: true)
}
public func popViewController() {
navigationController?.popViewController(animated: true)
}
public func savePasteboard(note: Note) {
let pboard = UIPasteboard.general
let pasteboardString: String? = pboard.string
if let content = pasteboardString {
note.content = NSMutableAttributedString(string: content)
}
if let image = pboard.image {
if let data = image.jpegData(compressionQuality: 1) {
guard let imagePath = ImagesProcessor.writeFile(data: data, note: note) else { return }
note.content = NSMutableAttributedString(string: ")\n\n")
}
}
if note.save() {
Storage.shared().add(note)
}
}
public func importSavedInSharedExtension() {
var notes = [Note]()
for url in UserDefaultsManagement.importURLs {
if let note = storage.importNote(url: url) {
notes.append(note)
}
}
notesTable.insertRows(notes: notes)
UserDefaultsManagement.importURLs = []
}
@objc func preferredContentSizeChanged() {
view.setNeedsLayout()
view.layoutIfNeeded()
}
@objc func rotated() {
guard isLandscape != nil else {
isLandscape = UIDevice.current.orientation.isLandscape
return
}
let isLand = UIDevice.current.orientation.isLandscape
if let landscape = self.isLandscape, landscape != isLand, !UIDevice.current.orientation.isFlat {
isLandscape = isLand
DispatchQueue.main.async {
self.loadNews()
self.resizeSidebar(withAnimation: true)
}
}
}
@objc func willExitForeground() {
importSavedInSharedExtension()
}
private var swipeStartLeadingConstant: CGFloat = 0
@objc func handleSidebarSwipe(_ swipe: UIPanGestureRecognizer) {
let notchWidth = getLeftInset()
let translation = swipe.translation(in: notesTable)
if swipe.state == .began {
maxSidebarWidth = calculateLabelMaxWidth()
sidebarTableView.isUserInteractionEnabled = true
if !UserDefaultsManagement.sidebarIsOpened {
self.sidebarTableLeadingConstraint.constant = -self.maxSidebarWidth
self.sidebarTableWidth.constant = self.maxSidebarWidth
self.notesTableLeadingConstraint.constant = 0
leftPreSafeArea.backgroundColor = UIColor.sidebar
notesTable.dragInteractionEnabled = false
sidebarTableView.isUserInteractionEnabled = false
swipeStartLeadingConstant = 0
} else {
let correctLeading = self.maxSidebarWidth + notchWidth
self.sidebarTableLeadingConstraint.constant = 0
self.sidebarTableWidth.constant = self.maxSidebarWidth
self.notesTableLeadingConstraint.constant = correctLeading
notesTable.dragInteractionEnabled = true
sidebarTableView.isUserInteractionEnabled = true
swipeStartLeadingConstant = correctLeading
}
return
}
if swipe.state == .changed {
let newLeading = swipeStartLeadingConstant + translation.x
let sidebarRange = maxSidebarWidth + notchWidth
guard newLeading >= 0 && newLeading <= sidebarRange else { return }
UIView.animate(withDuration: 0.075, delay: 0.0, options: .beginFromCurrentState, animations: {
self.notesTableLeadingConstraint.constant = newLeading
let sidebarOffset = max(0, newLeading - notchWidth)
let sidebarProgress = min(sidebarOffset, self.maxSidebarWidth) / self.maxSidebarWidth
self.sidebarTableLeadingConstraint.constant = -self.maxSidebarWidth * (1 - sidebarProgress)
self.view.layoutIfNeeded()
})
return
}
if swipe.state == .ended {
if translation.x > 0 {
showSidebar()
}
if translation.x < 0 {
hideSidebar()
}
}
}
private func initSidebar() {
if UserDefaultsManagement.sidebarIsOpened {
self.sidebarTableLeadingConstraint.constant = 0
self.notesTableLeadingConstraint.constant = self.maxSidebarWidth + getLeftInset()
self.notesTable.dragInteractionEnabled = true
self.sidebarTableView.isUserInteractionEnabled = true
} else {
self.notesTableLeadingConstraint.constant = 0
self.sidebarTableLeadingConstraint.constant = -self.maxSidebarWidth
self.sidebarTableWidth.constant = 0
// blue/blck pre safe area
leftPreSafeArea.backgroundColor = UIColor.sidebar
self.notesTable.dragInteractionEnabled = false
self.sidebarTableView.isUserInteractionEnabled = false
}
}
private func showSidebar() {
let leftInset = getLeftInset()
UIView.animate(withDuration: 0.2, delay: 0.0, options: .init(), animations: {
self.notesTableLeadingConstraint.constant = self.maxSidebarWidth + leftInset
self.sidebarTableLeadingConstraint.constant = 0
self.sidebarTableWidth.constant = self.maxSidebarWidth
self.view.layoutIfNeeded()
}) { _ in
UserDefaultsManagement.sidebarIsOpened = true
self.notesTable.dragInteractionEnabled = true
self.sidebarTableView.isUserInteractionEnabled = true
self.leftPreSafeArea.backgroundColor = UIColor.sidebar
}
}
private func hideSidebar() {
UIView.animate(withDuration: 0.2, delay: 0.0, options: .init(), animations: {
self.notesTableLeadingConstraint.constant = 0
self.sidebarTableLeadingConstraint.constant = -self.maxSidebarWidth
self.view.layoutIfNeeded()
}) { _ in
UserDefaultsManagement.sidebarIsOpened = false
self.notesTable.dragInteractionEnabled = false
self.sidebarTableView.isUserInteractionEnabled = false
// white pre safe area
self.leftPreSafeArea.backgroundColor = .whiteBlack
}
}
@objc func keyboardWillShow(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
//notesTableBottomContraint.constant = keyboardSize.height
sidebarTableBottomConstraint.constant = keyboardSize.height
}
}
@objc func keyboardWillHide(notification: NSNotification) {
//notesTableBottomContraint.constant = 0
sidebarTableBottomConstraint.constant = 0
}
public func refreshTextStorage(note: Note) {
DispatchQueue.main.async {
UIApplication.getEVC().fill(note: note)
}
}
private func calculateLabelMaxWidth() -> CGFloat {
var width = CGFloat(0)
var font = UIFont(name: "HelveticaNeue-BoldItalic", size: 15)
let fontMetrics = UIFontMetrics(forTextStyle: .title3)
font = fontMetrics.scaledFont(for: font!)
let settings = NSLocalizedString("Settings", comment: "Sidebar settings")
let untagged = NSLocalizedString("Untagged", comment: "Sidebar settings")
let inbox = NSLocalizedString("Inbox", comment: "Inbox in sidebar")
let notes = NSLocalizedString("Notes", comment: "Notes in sidebar")
let todo = NSLocalizedString("Todo", comment: "Todo in sidebar")
let trash = NSLocalizedString("Trash", comment: "Trash in sidebar")
var sidebarItems = [String]()
var tags = [String]()
if let project = storage.searchQuery.projects.first {
tags = sidebarTableView.getAllTags(projects: [project])
}
sidebarItems = tags + Storage.shared().getProjects().map({ $0.label })
+ [settings, inbox, notes, todo, trash, untagged]
for item in sidebarItems {
guard let font = font else { continue }
let labelWidth = (item as NSString).size(withAttributes: [.font: font]).width + 60
if labelWidth < (view.frame.size.width / 2) {
if labelWidth > width {
width = labelWidth
}
} else {
width = view.frame.size.width / 2
}
}
return width
}
public func unLock(notes: [Note], completion: @escaping ([Note]?) -> ()) {
getMasterPassword() { password in
self.unLock(notes: notes, completion: completion, password: password)
}
}
public func unLock(notes: [Note], completion: @escaping ([Note]?) -> (), password: String) {
for note in notes {
var success = [Note]()
if note.unLock(password: password) {
note.password = password
success.append(note)
}
DispatchQueue.main.async {
self.notesTable.reloadRowForce(note: note)
}
completion(success)
}
}
public func toggleNotesLock(notes: [Note]) {
var notes = notes
notes = lockUnlocked(notes: notes)
guard notes.count > 0 else { return }
getMasterPassword() { password in
for note in notes {
if note.container == .encryptedTextPack {
if note.unLock(password: password) {
note.password = password
DispatchQueue.main.async {
self.notesTable.reloadRowForce(note: note)
UIApplication.getEVC().fill(note: note)
UIApplication.getVC().openEditorViewController()
}
}
} else {
if note.encrypt(password: password) {
note.password = nil
DispatchQueue.main.async {
self.notesTable.reloadRowForce(note: note)
}
}
}
}
}
}
private func lockUnlocked(notes: [Note]) -> [Note] {
var notes = notes
var isFirst = true
for note in notes {
if note.isUnlocked() {
if note.lock() && isFirst {
note.password = nil
notesTable.reloadRowForce(note: note)
}
notes.removeAll { $0 === note }
}
isFirst = false
}
return notes
}
public func getMasterPassword(isUnlock: Bool = false, completion: @escaping (String) -> ()) {
let context = LAContext()
context.localizedFallbackTitle = NSLocalizedString("Enter Master Password", comment: "")
var passwordExist = false
do {
let item = KeychainPasswordItem(service: KeychainConfiguration.serviceName, account: "Master Password")
let password = try item.readPassword()
passwordExist = password.count > 0
} catch {/*_*/}
guard passwordExist && context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil) else {
masterPasswordPrompt(completion: completion)
return
}
context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: "To access master password") { (success, evaluateError) in
if !success {
self.masterPasswordPrompt(completion: completion)
return
}
do {
let item = KeychainPasswordItem(service: KeychainConfiguration.serviceName, account: "Master Password")
let password = try item.readPassword()
completion(password)
return
} catch {
print(error)
}
self.masterPasswordPrompt(completion: completion)
}
}
private func masterPasswordPrompt(completion: @escaping (String) -> ()) {
DispatchQueue.main.async {
let title = NSLocalizedString("Master password:", comment: "")
let alertController = UIAlertController(title: title, message: nil, preferredStyle: .alert)
alertController.addTextField(configurationHandler: {
[] (textField: UITextField) in
textField.placeholder = "mast3r passw0rd"
})
let confirmAction = UIAlertAction(title: "OK", style: .default) { (_) in
guard let password = alertController.textFields?[0].text, password.count > 0 else {
return
}
completion(password)
}
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { (_) in }
alertController.addAction(confirmAction)
alertController.addAction(cancelAction)
self.present(alertController, animated: true) {
alertController.textFields![0].selectAll(nil)
}
}
}
public func unlockPasswordPrompt(completion: @escaping (String) -> ()) {
DispatchQueue.main.async {
let title = NSLocalizedString("Password:", comment: "")
let alertController = UIAlertController(title: title, message: nil, preferredStyle: .alert)
alertController.addTextField(configurationHandler: {
[] (textField: UITextField) in
textField.placeholder = "note passw0rd"
textField.isSecureTextEntry = true
})
let confirmAction = UIAlertAction(title: "OK", style: .default) { (_) in
guard let password = alertController.textFields?[0].text, password.count > 0 else {
return
}
completion(password)
}
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { (_) in }
alertController.addAction(confirmAction)
alertController.addAction(cancelAction)
self.present(alertController, animated: true) {
alertController.textFields![0].selectAll(nil)
}
}
}
public func resizeSidebar(withAnimation: Bool = false) {
let leftInset = getLeftInset()
let width = calculateLabelMaxWidth()
maxSidebarWidth = width
guard UserDefaultsManagement.sidebarIsOpened else { return }
if maxSidebarWidth > view.frame.size.width {
maxSidebarWidth = view.frame.size.width / 2
}
if (withAnimation) {
UIView.animate(withDuration: 0.3, delay: 0, options: .beginFromCurrentState, animations: {
let width = self.maxSidebarWidth
self.notesTableLeadingConstraint.constant = width + leftInset
self.sidebarTableLeadingConstraint.constant = 0
self.sidebarTableWidth.constant = width
}) { _ in
}
} else {
notesTableLeadingConstraint.constant = maxSidebarWidth + leftInset
sidebarTableWidth.constant = maxSidebarWidth
}
}
public func restoreLastController() {
guard !self.storage.isCrashedLastTime,
let noteURL = UserDefaultsManagement.currentNote,
FileManager.default.fileExists(atPath: noteURL.path)
else { return }
let note = Storage.shared().addNote(url: noteURL)
guard !note.isEncrypted() else { return }
note.loadPreviewState()
UIApplication.getVC().openEditorViewController()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
UIApplication.getEVC().fill(note: note)
UIApplication.getEVC().configureNavMenu()
if UserDefaultsManagement.currentEditorState == true,
let selectedRange = UserDefaultsManagement.currentRange,
!note.previewState,
selectedRange.upperBound <= note.content.length
{
UIApplication.getEVC().editArea.becomeFirstResponder()
UIApplication.getEVC().editArea.selectedRange = selectedRange
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
UIApplication.getEVC().editArea.scrollRangeToVisible(selectedRange)
}
}
}
UserDefaultsManagement.currentNote = nil
}
public func reloadDatabase() {
Storage.instance = nil
storage = Storage.shared()
sidebarTableView.reloadSidebar()
initialLoadingState = false
viewDidLoad()
}
public func enableLockedProject() {
lockedProject.isHidden = false
clean()
}
public func disableLockedProject() {
lockedProject.isHidden = true
}
public func clean() {
notesTable.notes.removeAll()
notesTable.reloadData()
}
public func showAlert(message: String) {
DispatchQueue.main.async {
let title = NSLocalizedString("Web sharing error", comment: "")
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
let confirmAction = UIAlertAction(title: "OK", style: .default)
alertController.addAction(confirmAction)
self.present(alertController, animated: true)
}
}
public func buildSearchQuery() {
let searchQuery = SearchQuery()
var projects = [Project]()
var tags = [String]()
var type: SidebarItemType?
if let sidebarTableView = self.sidebarTableView, let indexPaths = sidebarTableView.indexPathsForSelectedRows {
for indexPath in indexPaths {
let item = sidebarTableView.sidebar.items[indexPath.section][indexPath.row]
if let project = item.project, !project.isVirtual {
projects.append(project)
}
if item.type == .Tag {
tags.append(item.name)
}
if item.type == .All ||
item.type == .Untagged ||
item.type == .Todo ||
item.type == .Trash ||
item.type == .Inbox {
type = item.type
}
}
}
if projects.count == 0 && type == nil {
type = .All
}
let filter = getSearchBar()?.text ?? ""
searchQuery.projects = projects
searchQuery.tags = tags
searchQuery.setFilter(filter)
if let type = type {
searchQuery.setType(type)
}
self.storage.setSearchQuery(value: searchQuery)
}
}
extension ViewController : UIPopoverPresentationControllerDelegate {
func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle {
return .none
}
}
extension UIApplication {
public func runInBackground(_ closure: @escaping () -> Void, expirationHandler: (() -> Void)? = nil) {
let taskID: UIBackgroundTaskIdentifier
if let expirationHandler = expirationHandler {
taskID = self.beginBackgroundTask(expirationHandler: expirationHandler)
} else {
taskID = self.beginBackgroundTask(expirationHandler: { })
}
DispatchQueue.global(qos: .background).sync {
closure()
}
self.endBackgroundTask(taskID)
}
}
================================================
FILE: FSNotes iOS/fr.lproj/Main.storyboard
================================================
================================================
FILE: FSNotes iOS/nl-NL.lproj/Main.storyboard
================================================
================================================
FILE: FSNotes iOS/pt-PT.lproj/Main.storyboard
================================================
================================================
FILE: FSNotes iOS/ru.lproj/InfoPlist.strings
================================================
"NSCameraUsageDescription" = "Требуется прикрепить фото к заметкам";
"NSFaceIDUsageDescription" = "Шифрование и дешифрование с помощью FaceID";
"NSLocationWhenInUseUsageDescription" = "Запрошено при прикреплении фотографии";
"NSPhotoLibraryAddUsageDescription" = "Требуется разрешение на запись изображений в приложении для фотографий";
"NSPhotoLibraryUsageDescription" = "Требуется прикрепление изображений к заметкам";
================================================
FILE: FSNotes iOS/ru.lproj/LaunchScreen.strings
================================================
================================================
FILE: FSNotes iOS/ru.lproj/Localizable.strings
================================================
/* Settings */
"+" = "+";
/* No comment provided by engineer. */
"..." = "...";
/* Settings */
"Add External Folder" = "Внешняя директория";
/* Settings */
"Advanced" = "Advanced";
/* Archive in sidebar */
"Archive" = "Архив";
/* No comment provided by engineer. */
"Are you sure you want to delete all versions of this note?" = "Вы уверены, что хотите удалить все версии этой заметки?";
/* No comment provided by engineer. */
"Are you sure you want to delete the history of all notes?" = "Вы уверены, что хотите удалить историю всех заметок?";
/* No comment provided by engineer. */
"Are you sure you want to delete this image?" = "Вы уверены, что хотите удалить это изображение?";
/* Settings */
"Auto Rename By Title" = "По заголовку";
/* Settings */
"Autocorrection" = "Aвтоисправление";
/* Settings */
"build" = "билд";
/* No comment provided by engineer. */
"Cancel" = "Отменить";
/* No comment provided by engineer. */
"Change Creation Date" = "Change Creation Date";
/* Settings */
"Check Spelling" = "Check Spelling";
/* No comment provided by engineer. */
"Code" = "Блок кода";
/* Settings */
"Code Block Live Highlighting" = "Code Block Live Highlighting";
/* Settings */
"Code Theme" = "Тема кода";
/* No comment provided by engineer. */
"Compatible with DayOne JSON (zip), Bear and Ulysses (textbundle), markdown, txt, rtf." = "Совместимо с DayOne JSON (zip), Bear and Ulysses (textbundle), markdown, txt, rtf.";
/* Settings */
"Container" = "Контейнер";
/* No comment provided by engineer. */
"Copy Plain Text" = "Copy Plain Text";
/* Main view popover table */
"Create Folder" = "Create Folder";
/* No comment provided by engineer. */
"Create folder:" = "Создать папку:";
/* No comment provided by engineer. */
"Create Web Page" = "Create Web Page";
/* No comment provided by engineer. */
"Creation Date" = "Creation Date";
/* Main view popover table */
"Decrypt" = "Decrypt";
/* Settings */
"Default Keyboard" = "Default Keyboard";
/* Table row action */
"Delete" = "Удалить";
/* No comment provided by engineer. */
"Delete Web Page" = "Delete Web Page";
/* No comment provided by engineer. */
"Documents" = "Документы";
/* No comment provided by engineer. */
"Done" = "Done";
/* No comment provided by engineer. */
"Duplicate" = "Создать копию";
/* Settings */
"Dynamic Type" = "Динамический шрифт";
/* Settings */
"Editor" = "Редактор";
/* Main view popover table */
"Empty Bin" = "Очистить корзину";
/* Main view popover table */
"Encrypt" = "Encrypt";
/* No comment provided by engineer. */
"Enter folder name" = "Введите название папки";
/* No comment provided by engineer. */
"Enter Master Password" = "Введите пароль";
/* No comment provided by engineer. */
"Enter new tag name" = "Введите название тега";
/* No comment provided by engineer. */
"Enter note name" = "Введите название заметки";
/* Settings */
"Extension" = "Расширение";
/* Settings */
"Family" = "Семейство шрифтов";
/* No comment provided by engineer. */
"File with this name already exist" = "Файл с таким именем уже существует";
/* Settings */
"Files" = "Files";
/* Settings */
"Files Naming" = "Именование файлов";
/* No comment provided by engineer. */
"Folder name:" = "Название папки:";
/* No comment provided by engineer. */
"Folder with this name already exist" = "Папка с таким именем уже существует";
/* Settings */
"Folders" = "Folders";
/* Settings */
"Font" = "Шрифт";
/* Settings */
"Font Family" = "Семейство шрифтов";
/* Settings */
"Font Size" = "Font Size";
/* Settings */
"Format: Untitled Note" = "Формат: Untitled Note";
/* Settings */
"Format: yyyy-MM-dd hh.mm.ss a" = "Формат: yyyy-MM-dd hh.mm.ss a";
/* Settings */
"Format: yyyyMMddHHmmss" = "Формат: yyyyMMddHHmmss";
/* Settings */
"FSNotes" = "FSNotes";
/* Settings */
"General" = "Основные";
/* Settings */
"Git" = "Git";
/* Main view popover table */
"Git Add/commit/push" = "Git Add/commit/push";
/* Main view popover table */
"Git Settings" = "Git Settings";
/* No comment provided by engineer. */
"History" = "История";
/* Settings */
"iCloud Drive" = "iCloud Drive";
/* Settings */
"Icon" = "Icon";
/* No comment provided by engineer. */
"Images source:" = "Источник изображения:";
/* Settings */
"Import Notes" = "Import Notes";
/* Inbox in sidebar */
"Inbox" = "Входящие";
/* No comment provided by engineer. */
"Invalid Password" = "Неверный пароль";
/* Settings */
"Library" = "Library";
/* Settings */
"Line Spacing" = "Межстрочный интервал";
/* Settings */
"Live Images Preview" = "Live Images Preview";
/* No comment provided by engineer. */
"Lock" = "Заблокировать";
/* Settings */
"Master" = "Master";
/* No comment provided by engineer. */
"Master password:" = "Мастер пароль:";
/* Settings */
"MathJax" = "MathJax";
/* No comment provided by engineer. */
"Modification Date" = "Modification Date";
/* Table row action */
"More" = "Ещё";
/* Move view */
"Move" = "Переместить";
/* No comment provided by engineer. */
"New Note" = "New Note";
/* No comment provided by engineer. */
"None" = "Умолчанию";
/* Notes in sidebar */
"Notes" = "Заметки";
/* No comment provided by engineer. */
"Notes List" = "Notes List";
/* Main view popover table */
"Open in Files.app" = "Открыть в Files.app";
/* Document opened */
"Open Note" = "Open Note";
/* No comment provided by engineer. */
"Passphrase" = "Passphrase";
/* No comment provided by engineer. */
"Password" = "Password";
/* No comment provided by engineer. */
"Password has been successfully changed" = "Password has been successfully changed";
/* No comment provided by engineer. */
"Password:" = "Password:";
/* No comment provided by engineer. */
"Photos" = "Фото";
/* No comment provided by engineer. */
"Picture removing" = "Удаление изображения";
/* Table row action */
"Pin" = "Прикрепить";
/* No comment provided by engineer. */
"Please enter valid password" = "Введите действующий пароль";
/* No comment provided by engineer. */
"Please try again" = "Please try again";
/* No comment provided by engineer. */
"Private Key" = "Private Key";
/* No comment provided by engineer. */
"Project removing ❌" = "Удаление проекта ❌";
/* No comment provided by engineer. */
"Public Key (optional)" = "Public Key (optional)";
/* No comment provided by engineer. */
"Pull (every 30 sec)" = "Pull (every 30 sec)";
/* No comment provided by engineer. */
"Remove Encryption" = "Remove Encryption";
/* Main view popover table */
"Remove Folder" = "Remove Folder";
/* Main view popover table */
"Remove Tag" = "Remove Tag";
/* No comment provided by engineer. */
"Rename" = "Переименовать";
/* Main view popover table */
"Rename Folder" = "Rename Folder";
/* Popover table */
"Rename folder:" = "Переименовать папку:";
/* No comment provided by engineer. */
"Rename note:" = "Переименовать заметку:";
/* Main view popover table */
"Rename Tag" = "Rename Tag";
/* Popover table */
"Rename tag:" = "Переименовать тег:";
/* No comment provided by engineer. */
"Save" = "Save";
/* No comment provided by engineer. */
"Save Clipboard" = "Save Clipboard";
/* No comment provided by engineer. */
"Save Revision" = "Save Revision";
/* No comment provided by engineer. */
"Saved versions" = "Сохраненные версии";
/* No comment provided by engineer. */
"Search or create" = "Найти или создать";
/* No comment provided by engineer. */
"Search or Create" = "Search or Create";
/* Settings */
"Security" = "Security";
/* Main view popover table */
"Select" = "Выбрать";
/* Sidebar settings */
"Settings" = "Наcтройки";
/* No comment provided by engineer. */
"Share" = "Поделиться";
/* No comment provided by engineer. */
"Show Folder in Library" = "Show Folder in Library";
/* No comment provided by engineer. */
"Show Notes in \"Notes\" and \"Todo\"" = "Show Notes in \"Notes\" and \"Todo\"";
/* Settings */
"Sort By" = "Sort By";
/* Settings */
"SoulverCore" = "SoulverCore";
/* Settings */
"Storage" = "Хранилище";
/* Settings */
"Support" = "Поддержка";
/* Settings */
"Thanks" = "Thanks";
/* Settings */
"Theme" = "Тема";
/* No comment provided by engineer. */
"Tip: To use old notes, you must decrypt them separately with the old key and encrypt them again." = "Tip: To use old notes, you must decrypt them separately with the old key and encrypt them again.";
/* No comment provided by engineer. */
"Title" = "Заголовку";
/* Sidebar items - Todo in sidebar */
"Todo" = "Todo";
/* Sidebar label - Trash in sidebar */
"Trash" = "Корзина";
/* Settings */
"Twitter" = "Twitter";
/* No comment provided by engineer. */
"Unlock" = "Разблокировать";
/* Table row action */
"Unpin" = "Unpin";
/* No comment provided by engineer. */
"Untagged" = "Без тегов";
/* No comment provided by engineer. */
"Update" = "Update";
/* No comment provided by engineer. */
"Use First Line as Title" = "Use First Line as Title";
/* No comment provided by engineer. */
"Use Inline Tags" = "Use Inline Tags";
/* No comment provided by engineer. */
"Verify Password" = "Verify Password";
/* Settings */
"Version" = "Версия";
/* No comment provided by engineer. */
"View" = "Вид";
/* Main view popover table */
"View Settings" = "View Settings";
/* No comment provided by engineer. */
"Visibility" = "Видимость";
/* No comment provided by engineer. */
"Web sharing error" = "Web sharing error";
/* Settings */
"Website" = "Website";
/* No comment provided by engineer. */
"Wrong password" = "Wrong password";
/* No comment provided by engineer. */
"Wrong repeated password" = "Wrong repeated password";
/* No comment provided by engineer. */
"Сlearing history" = "Очистка истории";
/* No comment provided by engineer. */
"✅ - " = "✅ - ";
================================================
FILE: FSNotes iOS/ru.lproj/Main.storyboard
================================================
================================================
FILE: FSNotes iOS/uk.lproj/Main.storyboard
================================================
================================================
FILE: FSNotes iOS Share/.bartycrouch.toml
================================================
[update]
tasks = ["interfaces", "code", "transform", "normalize"]
[update.interfaces]
paths = ["."]
defaultToBase = false
ignoreEmptyStrings = false
unstripped = false
[update.code]
codePaths = ["."]
localizablePaths = ["."]
defaultToKeys = true
additive = true
unstripped = false
plistArguments = true
[update.transform]
codePaths = ["."]
localizablePaths = ["."]
transformer = "foundation"
supportedLanguageEnumPath = "."
typeName = "BartyCrouch"
translateMethodName = "translate"
[update.normalize]
paths = ["."]
sourceLocale = "en"
harmonizeWithSource = true
sortByKeys = true
[lint]
paths = ["."]
duplicateKeys = true
emptyValues = true
================================================
FILE: FSNotes iOS Share/FSNotes iOS Share.entitlements
================================================
com.apple.developer.icloud-container-identifiers
iCloud.co.fluder.fsnotes
com.apple.developer.icloud-services
CloudDocuments
com.apple.developer.ubiquity-container-identifiers
iCloud.co.fluder.fsnotes
com.apple.developer.ubiquity-kvstore-identifier
$(TeamIdentifierPrefix)$(CFBundleIdentifier)
com.apple.security.application-groups
group.es.fsnot.user.defaults
================================================
FILE: FSNotes iOS Share/Info.plist
================================================
NSPrivacyAccessedAPITypes
NSPrivacyAccessedAPIType
NSPrivacyAccessedAPICategoryFileTimestamp
NSPrivacyAccessedAPITypeReasons
DDA9.1
NSPrivacyAccessedAPIType
NSPrivacyAccessedAPICategoryUserDefaults
NSPrivacyAccessedAPITypeReasons
CA92.1
CFBundleDevelopmentRegion
$(DEVELOPMENT_LANGUAGE)
CFBundleDisplayName
FSNotes
CFBundleExecutable
$(EXECUTABLE_NAME)
CFBundleIdentifier
$(PRODUCT_BUNDLE_IDENTIFIER)
CFBundleInfoDictionaryVersion
6.0
CFBundleName
$(PRODUCT_NAME)
CFBundlePackageType
XPC!
CFBundleShortVersionString
$(MARKETING_VERSION)
CFBundleVersion
$(CURRENT_PROJECT_VERSION)
NSExtension
NSExtensionAttributes
NSExtensionActivationRule
SUBQUERY (
extensionItems,
$extensionItem,
SUBQUERY (
$extensionItem.attachments,
$attachment,
ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.image"
).@count > 0
).@count == 1
OR
SUBQUERY (
extensionItems,
$extensionItem,
SUBQUERY (
$extensionItem.attachments,
$attachment,
ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.url"
).@count == 1
).@count == 1
OR
SUBQUERY (
extensionItems,
$extensionItem,
SUBQUERY (
$extensionItem.attachments,
$attachment,
ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.plain-text"
).@count == 1
).@count == 1
NSExtensionPointIdentifier
com.apple.share-services
NSExtensionPrincipalClass
ShareViewController
================================================
FILE: FSNotes iOS Share/Localizable.xcstrings
================================================
{
"sourceLanguage" : "en",
"strings" : {
"Inbox" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Příchozí"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "इनबॉक्स"
}
}
}
},
"New note" : {
"localizations" : {
"ar-IQ" : {
"stringUnit" : {
"state" : "translated",
"value" : "ملاحظة جديدة"
}
},
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nová poznámka"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Speichern"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nueva nota"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nouvelle note"
}
},
"he" : {
"stringUnit" : {
"state" : "translated",
"value" : "New note"
}
},
"hi" : {
"stringUnit" : {
"state" : "translated",
"value" : "नया नोट"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nuova nota"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "新規ノート"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "새 메모"
}
},
"nl-NL" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nieuwe notitie"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nova nota"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nova nota"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Сохранить"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Зберегти"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "新笔记"
}
}
}
}
},
"version" : "1.0"
}
================================================
FILE: FSNotes iOS Share/MainInterface.storyboard
================================================
================================================
FILE: FSNotes iOS Share/NSMutableAttributedString+.swift
================================================
//
// NSMutableAttributedString+.swift
// FSNotes
//
// Created by Oleksandr Hlushchenko on 14.11.2025.
// Copyright © 2025 Oleksandr Hlushchenko. All rights reserved.
//
import Foundation
#if os(OSX)
import AppKit
#else
import UIKit
#endif
extension NSMutableAttributedString {
convenience init(url: URL, title: String = "", path: String) {
self.init()
}
public func unloadImagesAndFiles() -> NSMutableAttributedString {
return self
}
public func loadImagesAndFiles(note: Note) {
}
public func unloadTasks() -> NSMutableAttributedString {
return self
}
public func loadTasks() {
}
public func unloadAttachments() -> NSMutableAttributedString {
return self
}
public func loadAttachments(_ note: Note) -> NSMutableAttributedString {
return self
}
public func replaceTag(name: String, with replaceString: String) {
}
public func getImagesAndFiles() -> [(url: URL, title: String, path: String)] {
return []
}
public func getMeta(at location: Int) -> (url: URL, title: String, path: String)? {
return nil
}
}
================================================
FILE: FSNotes iOS Share/ShareViewController.swift
================================================
//
// ShareViewController.swift
// FSNotes iOS Share
//
// Created by Oleksandr Glushchenko on 3/18/18.
// Copyright © 2018 Oleksandr Glushchenko. All rights reserved.
//
import UIKit
import MobileCoreServices
import Social
import UniformTypeIdentifiers
@objc(ShareViewController)
class ShareViewController: SLComposeServiceViewController {
// MARK: - Properties
private var hasImages = false
private var urlPreview: String?
// MARK: - Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
configureNavigationBar()
}
// MARK: - Configuration
private func configureNavigationBar() {
guard let navigationBar = navigationController?.navigationBar,
let rightButton = navigationBar.topItem?.rightBarButtonItem else {
return
}
rightButton.title = NSLocalizedString("New note", comment: "")
navigationBar.tintColor = .mainTheme
let titleLabel = UILabel(frame: CGRect(x: 0, y: 0, width: 50, height: 20))
titleLabel.text = "FSNotes"
titleLabel.font = UserDefaultsManagement.noteFont.bold().withSize(18)
navigationBar.topItem?.titleView = titleLabel
}
// MARK: - Preview
override func loadPreviewView() -> UIView! {
urlPreview = textView.text
guard let inputItems = extensionContext?.inputItems as? [NSExtensionItem] else {
return UIView()
}
processInputItems(inputItems)
return hasImages ? super.loadPreviewView() : UIView()
}
private func processInputItems(_ items: [NSExtensionItem]) {
for item in items {
guard let attachments = item.attachments else { continue }
for attachment in attachments {
if checkForImages(in: attachment) {
hasImages = true
textView.text = ""
return
}
loadURLIfNeeded(from: attachment)
}
}
}
private func checkForImages(in attachment: NSItemProvider) -> Bool {
return attachment.hasItemConformingToTypeIdentifier(kUTTypeImage as String) ||
attachment.hasItemConformingToTypeIdentifier(kUTTypeJPEG as String)
}
private func loadURLIfNeeded(from attachment: NSItemProvider) {
guard attachment.hasItemConformingToTypeIdentifier(kUTTypeURL as String) else {
return
}
attachment.loadItem(forTypeIdentifier: kUTTypeURL as String, options: nil) { [weak self] url, error in
guard let self = self,
let url = url as? URL,
error == nil else {
return
}
self.handleLoadedURL(url)
}
}
private func handleLoadedURL(_ url: URL) {
if url.absoluteString.starts(with: "file:///") {
loadFileContent(from: url)
} else {
updateTextViewWithURL(url)
}
}
private func loadFileContent(from url: URL) {
guard let fileData = try? Data(contentsOf: url),
let text = String(data: fileData, encoding: .utf8) else {
return
}
DispatchQueue.main.async { [weak self] in
self?.textView.text = text
}
}
private func updateTextViewWithURL(_ url: URL) {
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
let preview = self.urlPreview ?? ""
self.textView.text = "\(preview)\n\n\(url.absoluteString)".trimmingCharacters(in: .whitespacesAndNewlines)
}
}
// MARK: - Validation & Post
override func isContentValid() -> Bool {
return true
}
override func didSelectPost() {
saveNote()
}
override func configurationItems() -> [Any]! {
return []
}
// MARK: - Save Note
private func saveNote() {
guard let inputItems = extensionContext?.inputItems as? [NSExtensionItem] else {
closeExtension()
return
}
let note = createNote()
processAttachments(from: inputItems, note: note)
}
private func createNote() -> Note {
let note = Note()
Storage.shared().add(note)
var urls = UserDefaultsManagement.importURLs
urls.insert(note.url, at: 0)
UserDefaultsManagement.importURLs = urls
return note
}
private func appendTextContent(to note: Note) {
guard !textView.text.isEmpty else { return }
note.append(string: NSMutableAttributedString(string: textView.text))
}
private func processAttachments(from items: [NSExtensionItem], note: Note) {
var imageProviders: [NSItemProvider] = []
for item in items {
guard let attachments = item.attachments else { continue }
for provider in attachments {
if provider.hasItemConformingToTypeIdentifier(kUTTypeImage as String) {
imageProviders.append(provider)
} else if provider.hasItemConformingToTypeIdentifier(kUTTypeURL as String) {
processURLAttachment(note: note)
return
} else if provider.hasItemConformingToTypeIdentifier(kUTTypeText as String) {
processTextAttachment(note: note)
return
}
}
}
if imageProviders.isEmpty {
closeExtension()
} else {
processImageAttachments(imageProviders, note: note)
}
}
private func processImageAttachments(_ providers: [NSItemProvider], note: Note) {
let totalCount = providers.count
var processedCount = 0
for provider in providers {
provider.loadItem(forTypeIdentifier: kUTTypeImage as String, options: [:]) { [weak self] data, error in
guard let self = self, error == nil else {
processedCount += 1
if processedCount == totalCount {
self?.finalizeNoteSave(note)
}
return
}
let imageData = self.extractImageData(from: data)
let url = data as? URL
if let imageData = imageData {
note.append(image: imageData, url: url)
}
processedCount += 1
if processedCount == totalCount {
self.finalizeNoteSave(note)
}
}
}
}
private func extractImageData(from data: Any?) -> Data? {
if let data = data as? Data {
return data
} else if let image = data as? UIImage {
return image.jpegData(compressionQuality: 1)
} else if let url = data as? URL {
return try? Data(contentsOf: url)
}
return nil
}
private func processURLAttachment(note: Note) {
guard !hasImages, let contentText = contentText else {
closeExtension()
return
}
if let url = URL(string: contentText),
let data = try? Data(contentsOf: url),
let image = UIImage(data: data),
image.size.width > 0 {
note.append(image: data)
} else {
appendContentWithPrefix(contentText, to: note)
}
finalizeNoteSave(note)
}
private func processTextAttachment(note: Note) {
guard !hasImages, let contentText = contentText else {
closeExtension()
return
}
appendContentWithPrefix(contentText, to: note)
finalizeNoteSave(note)
}
private func appendContentWithPrefix(_ content: String, to note: Note) {
let prefix = note.content.length == 0 ? "" : "\n\n"
let string = NSMutableAttributedString(string: "\(prefix)\(content)")
note.append(string: string)
}
private func finalizeNoteSave(_ note: Note) {
if note.saveSimple() {
Storage.shared().add(note)
}
closeExtension()
}
private func closeExtension() {
extensionContext?.completeRequest(returningItems: extensionContext?.inputItems, completionHandler: nil)
}
}
================================================
FILE: FSNotes iOS Share/es.lproj/Localizable.strings
================================================
/* No comment provided by engineer. */
"Append to" = "";
/* No comment provided by engineer. */
"Choose for append" = "";
/* No comment provided by engineer. */
"New note" = "";
/* No comment provided by engineer. */
"Project" = "";
================================================
FILE: FSNotes iOS Share/pt.lproj/InfoPlist.strings
================================================
/* Bundle display name */
"CFBundleDisplayName" = "FSNotes";
/* Bundle name */
"CFBundleName" = "مشاركة";
================================================
FILE: FSNotes iOS Share/ru.lproj/InfoPlist.strings
================================================
================================================
FILE: FSNotes iOS Share/ru.lproj/Localizable.strings
================================================
/* No comment provided by engineer. */
"Append to" = "Добавить к заметке";
/* No comment provided by engineer. */
"Choose for append" = "Выбрать заметку для добавления";
/* No comment provided by engineer. */
"New note" = "Сохранить";
/* No comment provided by engineer. */
"Project" = "Добавить в проект";
================================================
FILE: FSNotes iOS Share/ru.lproj/MainInterface.strings
================================================
================================================
FILE: FSNotes iOS Share/uk.lproj/InfoPlist.strings
================================================
================================================
FILE: FSNotes iOS Share/uk.lproj/MainInterface.strings
================================================
================================================
FILE: FSNotes iOS Share/zh-Hans-CN.lproj/InfoPlist.strings
================================================
/* Bundle display name */
"CFBundleDisplayName" = "FSNotes";
/* Bundle name */
"CFBundleName" = "FSNotes iOS分享扩展";
================================================
FILE: FSNotes iOS Share/zh-Hans-CN.lproj/Localizable.strings
================================================
/* No comment provided by engineer. */
"Append to" = "附加到";
/* No comment provided by engineer. */
"Choose for append" = "选择追加";
/* No comment provided by engineer. */
"New note" = "新笔记";
/* No comment provided by engineer. */
"Project" = "项目";
================================================
FILE: FSNotes iOS Share/zh-Hans.lproj/MainInterface.strings
================================================
================================================
FILE: FSNotes.xcodeproj/project.pbxproj
================================================
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 60;
objects = {
/* Begin PBXBuildFile section */
1102DDB12EE4C280005029A6 /* EditTextView+Complete.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1102DDB02EE4C277005029A6 /* EditTextView+Complete.swift */; };
1102DDB22EE4C280005029A6 /* EditTextView+Complete.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1102DDB02EE4C277005029A6 /* EditTextView+Complete.swift */; };
110BE0112EE86B4A00C5E456 /* Clojure.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110BE0102EE86B4600C5E456 /* Clojure.swift */; };
110BE0122EE86B4A00C5E456 /* Clojure.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110BE0102EE86B4600C5E456 /* Clojure.swift */; };
110BE0132EE86B4A00C5E456 /* Clojure.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110BE0102EE86B4600C5E456 /* Clojure.swift */; };
110BE0152EE8C1C900C5E456 /* Html.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110BE0142EE8C1C600C5E456 /* Html.swift */; };
110BE0162EE8C1C900C5E456 /* Html.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110BE0142EE8C1C600C5E456 /* Html.swift */; };
110BE0172EE8C1C900C5E456 /* Html.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110BE0142EE8C1C600C5E456 /* Html.swift */; };
110BE0192EE8C25100C5E456 /* Css.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110BE0182EE8C24B00C5E456 /* Css.swift */; };
110BE01A2EE8C25100C5E456 /* Css.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110BE0182EE8C24B00C5E456 /* Css.swift */; };
110BE01B2EE8C25100C5E456 /* Css.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110BE0182EE8C24B00C5E456 /* Css.swift */; };
110BE01D2EE8C3BE00C5E456 /* Shell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110BE01C2EE8C3BA00C5E456 /* Shell.swift */; };
110BE01E2EE8C3BE00C5E456 /* Shell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110BE01C2EE8C3BA00C5E456 /* Shell.swift */; };
110BE01F2EE8C3BE00C5E456 /* Shell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110BE01C2EE8C3BA00C5E456 /* Shell.swift */; };
110BE0212EE8C53C00C5E456 /* TypeScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110BE0202EE8C53600C5E456 /* TypeScript.swift */; };
110BE0222EE8C53C00C5E456 /* TypeScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110BE0202EE8C53600C5E456 /* TypeScript.swift */; };
110BE0232EE8C53C00C5E456 /* TypeScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110BE0202EE8C53600C5E456 /* TypeScript.swift */; };
110BE0252EE8C5B000C5E456 /* Lisp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110BE0242EE8C5AC00C5E456 /* Lisp.swift */; };
110BE0262EE8C5B000C5E456 /* Lisp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110BE0242EE8C5AC00C5E456 /* Lisp.swift */; };
110BE0272EE8C5B000C5E456 /* Lisp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110BE0242EE8C5AC00C5E456 /* Lisp.swift */; };
110D09832E9C152B001555FA /* NSRange+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110D09812E9C1525001555FA /* NSRange+.swift */; };
110D09842E9C152B001555FA /* NSRange+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110D09812E9C1525001555FA /* NSRange+.swift */; };
110D09852E9C152B001555FA /* NSRange+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110D09812E9C1525001555FA /* NSRange+.swift */; };
110D09862E9C152B001555FA /* NSRange+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110D09812E9C1525001555FA /* NSRange+.swift */; };
110E409F2EA0150300C62F49 /* NSTextCheckingResult+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110E409D2EA0150000C62F49 /* NSTextCheckingResult+.swift */; };
110E40A02EA0150300C62F49 /* NSTextCheckingResult+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110E409D2EA0150000C62F49 /* NSTextCheckingResult+.swift */; };
110E40A12EA0150300C62F49 /* NSTextCheckingResult+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110E409D2EA0150000C62F49 /* NSTextCheckingResult+.swift */; };
110E40A22EA0150300C62F49 /* NSTextCheckingResult+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110E409D2EA0150000C62F49 /* NSTextCheckingResult+.swift */; };
110E40A42EA039CE00C62F49 /* EditTextView+DragOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110E40A32EA039AA00C62F49 /* EditTextView+DragOperation.swift */; };
110E40A52EA039CE00C62F49 /* EditTextView+DragOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110E40A32EA039AA00C62F49 /* EditTextView+DragOperation.swift */; };
111013152EC8F1B600B6CF1B /* ImagePreviewViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 111013142EC8F1B600B6CF1B /* ImagePreviewViewController.swift */; };
111013182ECA102200B6CF1B /* Pasteboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = D796EB40251E127300CE5C80 /* Pasteboard.swift */; };
113685522EC795B80033767F /* Data+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D77AD7FB27F9D1C90077BD45 /* Data+.swift */; };
113685532EC796EF0033767F /* Note.swift in Sources */ = {isa = PBXBuildFile; fileRef = D79FE8A01F77D04A00113CFD /* Note.swift */; };
1136855A2EC7A21F0033767F /* NSMutableAttributedString+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 113685592EC7A2130033767F /* NSMutableAttributedString+.swift */; };
1136855C2EC7A6A50033767F /* Platform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1136855B2EC7A69C0033767F /* Platform.swift */; };
1136855E2EC7A6A50033767F /* Platform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1136855B2EC7A69C0033767F /* Platform.swift */; };
1136855F2EC7A6A50033767F /* Platform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1136855B2EC7A69C0033767F /* Platform.swift */; };
113685602EC7A6A50033767F /* Platform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1136855B2EC7A69C0033767F /* Platform.swift */; };
113685622EC869950033767F /* URL+Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = 113685612EC869860033767F /* URL+Image.swift */; };
113685632EC869950033767F /* URL+Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = 113685612EC869860033767F /* URL+Image.swift */; };
113685642EC869950033767F /* URL+Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = 113685612EC869860033767F /* URL+Image.swift */; };
113685652EC869950033767F /* URL+Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = 113685612EC869860033767F /* URL+Image.swift */; };
113685682EC889E20033767F /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 113685672EC889DC0033767F /* SceneDelegate.swift */; };
1136856A2EC8AE2F0033767F /* UIBarButtonItem+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 113685692EC8AE260033767F /* UIBarButtonItem+.swift */; };
113A31A02EEE2D47009B50B0 /* Note+Preview.swift in Sources */ = {isa = PBXBuildFile; fileRef = 113A319F2EEE2D3A009B50B0 /* Note+Preview.swift */; };
113A31A12EEE2D47009B50B0 /* Note+Preview.swift in Sources */ = {isa = PBXBuildFile; fileRef = 113A319F2EEE2D3A009B50B0 /* Note+Preview.swift */; };
113A31A22EEE2D47009B50B0 /* Note+Preview.swift in Sources */ = {isa = PBXBuildFile; fileRef = 113A319F2EEE2D3A009B50B0 /* Note+Preview.swift */; };
113A31A32EEE2D47009B50B0 /* Note+Preview.swift in Sources */ = {isa = PBXBuildFile; fileRef = 113A319F2EEE2D3A009B50B0 /* Note+Preview.swift */; };
113EEBD72EDBA63D00A94F29 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D7DB5ED520248D5500E7E1B6 /* Assets.xcassets */; };
11598DA32EDCB8D40036E387 /* UIFont+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11598DA22EDCB8D40036E387 /* UIFont+.swift */; };
11598DA42EDCB9B40036E387 /* UIFont+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11598DA22EDCB8D40036E387 /* UIFont+.swift */; };
1161828D2E637E31005B5EE0 /* SwiftHighlighter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 116182862E62B046005B5EE0 /* SwiftHighlighter.swift */; };
1161828E2E637E31005B5EE0 /* SwiftHighlighter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 116182862E62B046005B5EE0 /* SwiftHighlighter.swift */; };
1161828F2E637E31005B5EE0 /* SwiftHighlighter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 116182862E62B046005B5EE0 /* SwiftHighlighter.swift */; };
1166D1F72E91BA8800B061CA /* CodeBlockDetector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1166D1F62E91BA7F00B061CA /* CodeBlockDetector.swift */; };
1166D1F82E91BA8800B061CA /* CodeBlockDetector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1166D1F62E91BA7F00B061CA /* CodeBlockDetector.swift */; };
1166D1F92E91BA8800B061CA /* CodeBlockDetector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1166D1F62E91BA7F00B061CA /* CodeBlockDetector.swift */; };
1175E0922EDC929400B92794 /* ny-2026.icon in Resources */ = {isa = PBXBuildFile; fileRef = 1175E0912EDC929400B92794 /* ny-2026.icon */; };
117C0E4D2EEDB9C30086419C /* EditTextView+Clicked.swift in Sources */ = {isa = PBXBuildFile; fileRef = 117C0E4C2EEDB9B70086419C /* EditTextView+Clicked.swift */; };
117C0E4E2EEDB9C40086419C /* EditTextView+Clicked.swift in Sources */ = {isa = PBXBuildFile; fileRef = 117C0E4C2EEDB9B70086419C /* EditTextView+Clicked.swift */; };
11A6A8FA2EF06B9D005D000A /* EditTextView+MoveLines.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11A6A8F92EF06B90005D000A /* EditTextView+MoveLines.swift */; };
11A6A8FB2EF06B9D005D000A /* EditTextView+MoveLines.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11A6A8F92EF06B90005D000A /* EditTextView+MoveLines.swift */; };
11A6A8FD2EF074D8005D000A /* EditTextView+Todo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11A6A8FC2EF074D2005D000A /* EditTextView+Todo.swift */; };
11A6A8FE2EF074D8005D000A /* EditTextView+Todo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11A6A8FC2EF074D2005D000A /* EditTextView+Todo.swift */; };
11A95B622EDC56DC0081ED29 /* modern.icon in Resources */ = {isa = PBXBuildFile; fileRef = 11A95B612EDC56DC0081ED29 /* modern.icon */; };
11AA4B1F2EF9A47A0075A9E4 /* EditorViewController+ScrollPosition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11AA4B1E2EF9A4680075A9E4 /* EditorViewController+ScrollPosition.swift */; };
11AA4B202EF9A47A0075A9E4 /* EditorViewController+ScrollPosition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11AA4B1E2EF9A4680075A9E4 /* EditorViewController+ScrollPosition.swift */; };
11ABE5E22EEEFD0E00E7C9EB /* NotesCounterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11ABE5E12EEEFCF700E7C9EB /* NotesCounterView.swift */; };
11ABE5E32EEEFD0E00E7C9EB /* NotesCounterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11ABE5E12EEEFCF700E7C9EB /* NotesCounterView.swift */; };
11AF633E2E898435004E7157 /* Sql.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11AF633D2E898430004E7157 /* Sql.swift */; };
11AF633F2E898435004E7157 /* Sql.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11AF633D2E898430004E7157 /* Sql.swift */; };
11AF63402E898435004E7157 /* Sql.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11AF633D2E898430004E7157 /* Sql.swift */; };
11B3F5962F182E5900A3531D /* EditorViewController+Search.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11B3F5952F182E4E00A3531D /* EditorViewController+Search.swift */; };
11BD71662EDC87B700541BF9 /* classic-2025.icon in Resources */ = {isa = PBXBuildFile; fileRef = 11BD71652EDC87B700541BF9 /* classic-2025.icon */; };
11BD8F922EDDEC3D000673A7 /* GitHubDark.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11BD8F912EDDEC33000673A7 /* GitHubDark.swift */; };
11BD8F932EDDEC3D000673A7 /* GitHubDark.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11BD8F912EDDEC33000673A7 /* GitHubDark.swift */; };
11BD8F942EDDEC3D000673A7 /* GitHubDark.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11BD8F912EDDEC33000673A7 /* GitHubDark.swift */; };
11BD8F962EDDF32E000673A7 /* SolarizedLight.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11BD8F952EDDF320000673A7 /* SolarizedLight.swift */; };
11BD8F972EDDF32E000673A7 /* SolarizedLight.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11BD8F952EDDF320000673A7 /* SolarizedLight.swift */; };
11BD8F982EDDF32E000673A7 /* SolarizedLight.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11BD8F952EDDF320000673A7 /* SolarizedLight.swift */; };
11BD8F9A2EDDF336000673A7 /* SolarizedDark.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11BD8F992EDDF332000673A7 /* SolarizedDark.swift */; };
11BD8F9B2EDDF336000673A7 /* SolarizedDark.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11BD8F992EDDF332000673A7 /* SolarizedDark.swift */; };
11BD8F9C2EDDF336000673A7 /* SolarizedDark.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11BD8F992EDDF332000673A7 /* SolarizedDark.swift */; };
11BD8F9E2EDE0235000673A7 /* AtomOneLight.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11BD8F9D2EDE022C000673A7 /* AtomOneLight.swift */; };
11BD8F9F2EDE0235000673A7 /* AtomOneLight.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11BD8F9D2EDE022C000673A7 /* AtomOneLight.swift */; };
11BD8FA02EDE0235000673A7 /* AtomOneLight.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11BD8F9D2EDE022C000673A7 /* AtomOneLight.swift */; };
11BD8FA22EDE024D000673A7 /* AtomOneDark.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11BD8FA12EDE023E000673A7 /* AtomOneDark.swift */; };
11BD8FA32EDE024D000673A7 /* AtomOneDark.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11BD8FA12EDE023E000673A7 /* AtomOneDark.swift */; };
11BD8FA42EDE024D000673A7 /* AtomOneDark.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11BD8FA12EDE023E000673A7 /* AtomOneDark.swift */; };
11BD8FA62EDE0683000673A7 /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11BD8FA52EDE0679000673A7 /* Theme.swift */; };
11BD8FA72EDE0683000673A7 /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11BD8FA52EDE0679000673A7 /* Theme.swift */; };
11BD8FA82EDE0683000673A7 /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11BD8FA52EDE0679000673A7 /* Theme.swift */; };
11BD8FAA2EDE1AF8000673A7 /* UserDataService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F13BB3820FEDE230005E120 /* UserDataService.swift */; };
11BD8FAB2EDE1AF8000673A7 /* UserDataService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F13BB3820FEDE230005E120 /* UserDataService.swift */; };
11BF066A2EE331B5006C7336 /* Scala.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11BF06692EE331B2006C7336 /* Scala.swift */; };
11BF066B2EE331B5006C7336 /* Scala.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11BF06692EE331B2006C7336 /* Scala.swift */; };
11BF066C2EE331B5006C7336 /* Scala.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11BF06692EE331B2006C7336 /* Scala.swift */; };
11BF066E2EE33201006C7336 /* Bash.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11BF066D2EE331FE006C7336 /* Bash.swift */; };
11BF066F2EE33201006C7336 /* Bash.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11BF066D2EE331FE006C7336 /* Bash.swift */; };
11BF06702EE33201006C7336 /* Bash.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11BF066D2EE331FE006C7336 /* Bash.swift */; };
11BF06722EE33262006C7336 /* Haskell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11BF06712EE3325F006C7336 /* Haskell.swift */; };
11BF06732EE33262006C7336 /* Haskell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11BF06712EE3325F006C7336 /* Haskell.swift */; };
11BF06742EE33262006C7336 /* Haskell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11BF06712EE3325F006C7336 /* Haskell.swift */; };
11BF06762EE49546006C7336 /* Lua.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11BF06752EE49542006C7336 /* Lua.swift */; };
11BF06772EE49546006C7336 /* Lua.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11BF06752EE49542006C7336 /* Lua.swift */; };
11BF06782EE49546006C7336 /* Lua.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11BF06752EE49542006C7336 /* Lua.swift */; };
11BF067A2EE495C2006C7336 /* Perl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11BF06792EE495C0006C7336 /* Perl.swift */; };
11BF067B2EE495C2006C7336 /* Perl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11BF06792EE495C0006C7336 /* Perl.swift */; };
11BF067C2EE495C2006C7336 /* Perl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11BF06792EE495C0006C7336 /* Perl.swift */; };
11BF067E2EE4968C006C7336 /* Erlang.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11BF067D2EE49689006C7336 /* Erlang.swift */; };
11BF067F2EE4968C006C7336 /* Erlang.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11BF067D2EE49689006C7336 /* Erlang.swift */; };
11BF06802EE4968C006C7336 /* Erlang.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11BF067D2EE49689006C7336 /* Erlang.swift */; };
11D6C0C72EE2256B006017F0 /* Python.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0C62EE22567006017F0 /* Python.swift */; };
11D6C0C82EE2256B006017F0 /* Python.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0C62EE22567006017F0 /* Python.swift */; };
11D6C0C92EE2256B006017F0 /* Python.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0C62EE22567006017F0 /* Python.swift */; };
11D6C0CB2EE225E7006017F0 /* C.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0CA2EE225E1006017F0 /* C.swift */; };
11D6C0CC2EE225E7006017F0 /* C.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0CA2EE225E1006017F0 /* C.swift */; };
11D6C0CD2EE225E7006017F0 /* C.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0CA2EE225E1006017F0 /* C.swift */; };
11D6C0CF2EE2279E006017F0 /* Cpp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0CE2EE22799006017F0 /* Cpp.swift */; };
11D6C0D02EE2279E006017F0 /* Cpp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0CE2EE22799006017F0 /* Cpp.swift */; };
11D6C0D12EE2279E006017F0 /* Cpp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0CE2EE22799006017F0 /* Cpp.swift */; };
11D6C0D32EE227F9006017F0 /* Java.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0D22EE227F6006017F0 /* Java.swift */; };
11D6C0D42EE227F9006017F0 /* Java.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0D22EE227F6006017F0 /* Java.swift */; };
11D6C0D52EE227F9006017F0 /* Java.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0D22EE227F6006017F0 /* Java.swift */; };
11D6C0D72EE229E9006017F0 /* Go.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0D62EE229E7006017F0 /* Go.swift */; };
11D6C0D82EE229E9006017F0 /* Go.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0D62EE229E7006017F0 /* Go.swift */; };
11D6C0D92EE229E9006017F0 /* Go.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0D62EE229E7006017F0 /* Go.swift */; };
11D6C0DB2EE22B0F006017F0 /* Rust.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0DA2EE22B0D006017F0 /* Rust.swift */; };
11D6C0DC2EE22B0F006017F0 /* Rust.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0DA2EE22B0D006017F0 /* Rust.swift */; };
11D6C0DD2EE22B0F006017F0 /* Rust.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0DA2EE22B0D006017F0 /* Rust.swift */; };
11D6C0DF2EE22B77006017F0 /* Csharp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0DE2EE22B74006017F0 /* Csharp.swift */; };
11D6C0E02EE22B77006017F0 /* Csharp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0DE2EE22B74006017F0 /* Csharp.swift */; };
11D6C0E12EE22B77006017F0 /* Csharp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0DE2EE22B74006017F0 /* Csharp.swift */; };
11D6C0E32EE22BF2006017F0 /* Kotlin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0E22EE22BEE006017F0 /* Kotlin.swift */; };
11D6C0E42EE22BF2006017F0 /* Kotlin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0E22EE22BEE006017F0 /* Kotlin.swift */; };
11D6C0E52EE22BF2006017F0 /* Kotlin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0E22EE22BEE006017F0 /* Kotlin.swift */; };
11D6C0E72EE22C11006017F0 /* R.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0E62EE22C0F006017F0 /* R.swift */; };
11D6C0E82EE22C11006017F0 /* R.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0E62EE22C0F006017F0 /* R.swift */; };
11D6C0E92EE22C11006017F0 /* R.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0E62EE22C0F006017F0 /* R.swift */; };
11D6C0EB2EE22C6B006017F0 /* Ruby.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0EA2EE22C69006017F0 /* Ruby.swift */; };
11D6C0EC2EE22C6B006017F0 /* Ruby.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0EA2EE22C69006017F0 /* Ruby.swift */; };
11D6C0ED2EE22C6B006017F0 /* Ruby.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0EA2EE22C69006017F0 /* Ruby.swift */; };
11D6C0EF2EE22CBC006017F0 /* Matlab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0EE2EE22CB8006017F0 /* Matlab.swift */; };
11D6C0F02EE22CBC006017F0 /* Matlab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0EE2EE22CB8006017F0 /* Matlab.swift */; };
11D6C0F12EE22CBC006017F0 /* Matlab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0EE2EE22CB8006017F0 /* Matlab.swift */; };
11D6C0F32EE22D3B006017F0 /* Dart.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0F22EE22D39006017F0 /* Dart.swift */; };
11D6C0F42EE22D3B006017F0 /* Dart.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0F22EE22D39006017F0 /* Dart.swift */; };
11D6C0F52EE22D3B006017F0 /* Dart.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0F22EE22D39006017F0 /* Dart.swift */; };
11D6C0F72EE22D78006017F0 /* Vb.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0F62EE22D73006017F0 /* Vb.swift */; };
11D6C0F82EE22D78006017F0 /* Vb.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0F62EE22D73006017F0 /* Vb.swift */; };
11D6C0F92EE22D78006017F0 /* Vb.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0F62EE22D73006017F0 /* Vb.swift */; };
11D6C0FB2EE22E00006017F0 /* Assembly.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0FA2EE22DFC006017F0 /* Assembly.swift */; };
11D6C0FC2EE22E00006017F0 /* Assembly.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0FA2EE22DFC006017F0 /* Assembly.swift */; };
11D6C0FD2EE22E00006017F0 /* Assembly.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0FA2EE22DFC006017F0 /* Assembly.swift */; };
11D6C0FF2EE22E4A006017F0 /* Scratch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0FE2EE22E48006017F0 /* Scratch.swift */; };
11D6C1002EE22E4A006017F0 /* Scratch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0FE2EE22E48006017F0 /* Scratch.swift */; };
11D6C1012EE22E4A006017F0 /* Scratch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C0FE2EE22E48006017F0 /* Scratch.swift */; };
11D6C1032EE22E8F006017F0 /* Groovy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C1022EE22E8B006017F0 /* Groovy.swift */; };
11D6C1042EE22E8F006017F0 /* Groovy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C1022EE22E8B006017F0 /* Groovy.swift */; };
11D6C1052EE22E8F006017F0 /* Groovy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C1022EE22E8B006017F0 /* Groovy.swift */; };
11D6C1072EE22EED006017F0 /* ObjectiveC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C1062EE22EE8006017F0 /* ObjectiveC.swift */; };
11D6C1082EE22EED006017F0 /* ObjectiveC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C1062EE22EE8006017F0 /* ObjectiveC.swift */; };
11D6C1092EE22EED006017F0 /* ObjectiveC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D6C1062EE22EE8006017F0 /* ObjectiveC.swift */; };
11D702A62E5ADDED004DBAEC /* LayoutManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D702A52E5ADDE2004DBAEC /* LayoutManager.swift */; };
11D702A72E5ADDED004DBAEC /* LayoutManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D702A52E5ADDE2004DBAEC /* LayoutManager.swift */; };
11D702AC2E5B8E0C004DBAEC /* HtmlExtractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D702AB2E5B8E02004DBAEC /* HtmlExtractor.swift */; };
11D702AD2E5B8E0C004DBAEC /* HtmlExtractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D702AB2E5B8E02004DBAEC /* HtmlExtractor.swift */; };
11D702AE2E5B8E0C004DBAEC /* HtmlExtractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D702AB2E5B8E02004DBAEC /* HtmlExtractor.swift */; };
11D9431A2E643EF40010CC2B /* JavaScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D943192E643EF20010CC2B /* JavaScript.swift */; };
11D9431B2E643EF40010CC2B /* JavaScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D943192E643EF20010CC2B /* JavaScript.swift */; };
11D9431C2E643EF40010CC2B /* JavaScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D943192E643EF20010CC2B /* JavaScript.swift */; };
11D9431E2E643F250010CC2B /* Swift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D9431D2E643F1F0010CC2B /* Swift.swift */; };
11D9431F2E643F250010CC2B /* Swift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D9431D2E643F1F0010CC2B /* Swift.swift */; };
11D943202E643F250010CC2B /* Swift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D9431D2E643F1F0010CC2B /* Swift.swift */; };
11D943222E643F410010CC2B /* Php.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D943212E643F3B0010CC2B /* Php.swift */; };
11D943232E643F410010CC2B /* Php.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D943212E643F3B0010CC2B /* Php.swift */; };
11D943242E643F410010CC2B /* Php.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D943212E643F3B0010CC2B /* Php.swift */; };
11D943272E643F630010CC2B /* GitHubLight.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D943262E643F5E0010CC2B /* GitHubLight.swift */; };
11D943282E643F630010CC2B /* GitHubLight.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D943262E643F5E0010CC2B /* GitHubLight.swift */; };
11D943292E643F630010CC2B /* GitHubLight.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11D943262E643F5E0010CC2B /* GitHubLight.swift */; };
11F018AC2EF7E78600F07580 /* MPreviewFindPanel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11F018AB2EF7E77B00F07580 /* MPreviewFindPanel.swift */; };
11F018AD2EF7E78600F07580 /* MPreviewFindPanel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11F018AB2EF7E77B00F07580 /* MPreviewFindPanel.swift */; };
11F018B22EF8415600F07580 /* MPreviewContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11F018B12EF8415200F07580 /* MPreviewContainerView.swift */; };
11F018B32EF8415600F07580 /* MPreviewContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11F018B12EF8415200F07580 /* MPreviewContainerView.swift */; };
11F1771A2EF1E93500CC566F /* ViewController+Menu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11F177192EF1E92C00CC566F /* ViewController+Menu.swift */; };
11F1771B2EF1E93500CC566F /* ViewController+Menu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11F177192EF1E92C00CC566F /* ViewController+Menu.swift */; };
11F2D4F42F104322002E4E47 /* Project+Date.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11F2D4F32F1042F4002E4E47 /* Project+Date.swift */; };
11F2D4F52F104322002E4E47 /* Project+Date.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11F2D4F32F1042F4002E4E47 /* Project+Date.swift */; };
11F2D4F62F104322002E4E47 /* Project+Date.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11F2D4F32F1042F4002E4E47 /* Project+Date.swift */; };
11F2D4F72F104322002E4E47 /* Project+Date.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11F2D4F32F1042F4002E4E47 /* Project+Date.swift */; };
11F389562EEA10930008EC18 /* Mermaid.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11F389552EEA108C0008EC18 /* Mermaid.swift */; };
11F389572EEA10930008EC18 /* Mermaid.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11F389552EEA108C0008EC18 /* Mermaid.swift */; };
11F389582EEA10930008EC18 /* Mermaid.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11F389552EEA108C0008EC18 /* Mermaid.swift */; };
11F3F4832EDB0E0B00435CBF /* URL+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F13BB2A20FEDE230005E120 /* URL+.swift */; };
11F3F4842EDB0E0B00435CBF /* URL+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F13BB2A20FEDE230005E120 /* URL+.swift */; };
11F3F4852EDB0E2A00435CBF /* String+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F13BB2920FEDE230005E120 /* String+.swift */; };
11F3F4862EDB0E2A00435CBF /* String+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F13BB2920FEDE230005E120 /* String+.swift */; };
11F3F4872EDB0E4400435CBF /* DateFormatter+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F13BB2820FEDE230005E120 /* DateFormatter+.swift */; };
11F3F4882EDB0E4400435CBF /* DateFormatter+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F13BB2820FEDE230005E120 /* DateFormatter+.swift */; };
11F43F3C2F127EE300652350 /* Meet FSNotes 7.textbundle in Resources */ = {isa = PBXBuildFile; fileRef = 11F43F3A2F127C6900652350 /* Meet FSNotes 7.textbundle */; };
11F5D53B2EFDA17000A66466 /* modern.icon in Resources */ = {isa = PBXBuildFile; fileRef = 11F5D53A2EFDA17000A66466 /* modern.icon */; };
11F5D53C2EFDA17000A66466 /* modern.icon in Resources */ = {isa = PBXBuildFile; fileRef = 11F5D53A2EFDA17000A66466 /* modern.icon */; };
275592971F3AE9B5006B8988 /* MainWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 275592961F3AE9B5006B8988 /* MainWindowController.swift */; };
2799407C218484C900727B20 /* TitleBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2799407B218484C900727B20 /* TitleBarView.swift */; };
42E001C62ADAC2930099E7AD /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 42E001C52ADAC2930099E7AD /* Localizable.xcstrings */; };
42E001C72ADAC2930099E7AD /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 42E001C52ADAC2930099E7AD /* Localizable.xcstrings */; };
42E001CA2ADAC2930099E7AD /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 42E001C92ADAC2930099E7AD /* Localizable.xcstrings */; };
42E001CC2ADAC2930099E7AD /* InfoPlist.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 42E001CB2ADAC2930099E7AD /* InfoPlist.xcstrings */; };
42E001CF2ADAC2930099E7AD /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 42E001CE2ADAC2930099E7AD /* Localizable.xcstrings */; };
48BEA1E16CCED6900AD756F7 /* Pods_FSNotes_iOS_Share_Extension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 99068B82274CF88F23C4761D /* Pods_FSNotes_iOS_Share_Extension.framework */; };
8F7136EE23490CBF004DFA6E /* Markdown.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F7136ED23490CBF004DFA6E /* Markdown.swift */; };
8F7136F023490CBF004DFA6E /* Markdown.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F7136ED23490CBF004DFA6E /* Markdown.swift */; };
BE957A4A1B908EC91BECB3D3 /* Pods_FSNotes__iCloud_.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6066605B9BAF43A4BF3B60C1 /* Pods_FSNotes__iCloud_.framework */; };
CE3427A778205E1713A014B9 /* Pods_FSNotes_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 85B72F46887638CA9CC70D39 /* Pods_FSNotes_iOS.framework */; };
D4DB932C9F51CAE71393A28B /* Pods_FSNotes.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F616385FF783029192B97DF6 /* Pods_FSNotes.framework */; };
D7013E0026C3B116006F58E3 /* NSColor+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7013DFF26C3B116006F58E3 /* NSColor+.swift */; };
D7013E0126C3B116006F58E3 /* NSColor+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7013DFF26C3B116006F58E3 /* NSColor+.swift */; };
D7038E2620FB24E000A54E69 /* NoteAttachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7038E2520FB24E000A54E69 /* NoteAttachment.swift */; };
D7038E2720FB24E000A54E69 /* NoteAttachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7038E2520FB24E000A54E69 /* NoteAttachment.swift */; };
D706396A202230BB00BC8446 /* EditorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7063969202230BB00BC8446 /* EditorViewController.swift */; };
D70716DC2307E82900B44B0D /* SingleImageTouchDownGestureRecognizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D70716DB2307E82900B44B0D /* SingleImageTouchDownGestureRecognizer.swift */; };
D708AC672000EF5800A1760F /* NoteType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D708AC662000EF5800A1760F /* NoteType.swift */; };
D708AC682000F0E100A1760F /* NoteType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D708AC662000EF5800A1760F /* NoteType.swift */; };
D709C9E229AFD9E0006EF9A8 /* GitTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D709C9E129AFD9E0006EF9A8 /* GitTableViewCell.swift */; };
D70B1FAB29213EDF003923DC /* HyperlinkTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = D70B1FAA29213EDF003923DC /* HyperlinkTextField.swift */; };
D70B1FAC29213EE0003923DC /* HyperlinkTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = D70B1FAA29213EDF003923DC /* HyperlinkTextField.swift */; };
D70E9DEE2901AE9100A3C634 /* Branch.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC5628EB5EBE008B3BBC /* Branch.swift */; };
D70E9DEF2901AE9400A3C634 /* Branches.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC5728EB5EBE008B3BBC /* Branches.swift */; };
D70E9DF02901AE9700A3C634 /* BranchesIterator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC5828EB5EBE008B3BBC /* BranchesIterator.swift */; };
D70E9DF12901AE9B00A3C634 /* KeyAuthentication.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC6E28EB5EC0008B3BBC /* KeyAuthentication.swift */; };
D70E9DF22901AE9E00A3C634 /* Authentication.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC6F28EB5EC0008B3BBC /* Authentication.swift */; };
D70E9DF32901AEA100A3C634 /* PasswordAuthentication.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC7028EB5EC0008B3BBC /* PasswordAuthentication.swift */; };
D70E9DF42901AEA800A3C634 /* Commit.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC5428EB5EBE008B3BBC /* Commit.swift */; };
D70E9DF52901AEAF00A3C634 /* Blob.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC5F28EB5EBE008B3BBC /* Blob.swift */; };
D70E9DF62901AEAF00A3C634 /* Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC5C28EB5EBE008B3BBC /* Error.swift */; };
D70E9DF72901AEAF00A3C634 /* ConfigManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC5B28EB5EBE008B3BBC /* ConfigManager.swift */; };
D70E9DF82901AEAF00A3C634 /* Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC5A28EB5EBE008B3BBC /* Strings.swift */; };
D70E9DF92901AEAF00A3C634 /* Progress.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC5E28EB5EBE008B3BBC /* Progress.swift */; };
D70E9DFA2901AEAF00A3C634 /* Signature.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC6128EB5EBF008B3BBC /* Signature.swift */; };
D70E9DFB2901AEAF00A3C634 /* Object.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC6228EB5EBF008B3BBC /* Object.swift */; };
D70E9DFC2901AEAF00A3C634 /* Wrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC5D28EB5EBE008B3BBC /* Wrapper.swift */; };
D70E9DFD2901AEAF00A3C634 /* OID.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC6028EB5EBF008B3BBC /* OID.swift */; };
D70E9DFE2901AEAF00A3C634 /* StaticSshKeyDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7E32C2B28F8D0740048614B /* StaticSshKeyDelegate.swift */; };
D70E9DFF2901AEAF00A3C634 /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = D771E96E28EDFBF600CD4871 /* Errors.swift */; };
D70E9E002901AEB600A3C634 /* Diff.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC6C28EB5EC0008B3BBC /* Diff.swift */; };
D70E9E012901AEB600A3C634 /* DiffEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC6B28EB5EC0008B3BBC /* DiffEntry.swift */; };
D70E9E022901AEBF00A3C634 /* Head.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC7E28EB5EC2008B3BBC /* Head.swift */; };
D70E9E032901AEBF00A3C634 /* Head+Checkout.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC7D28EB5EC2008B3BBC /* Head+Checkout.swift */; };
D70E9E042901AEBF00A3C634 /* Head+Merge.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC7F28EB5EC2008B3BBC /* Head+Merge.swift */; };
D70E9E052901AEC400A3C634 /* Index+Files.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC7B28EB5EC1008B3BBC /* Index+Files.swift */; };
D70E9E062901AEC400A3C634 /* Index.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC7928EB5EC1008B3BBC /* Index.swift */; };
D70E9E072901AEC400A3C634 /* Index+Commit.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC7A28EB5EC1008B3BBC /* Index+Commit.swift */; };
D70E9E082901AEC900A3C634 /* Reference.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC8A28EB5EC3008B3BBC /* Reference.swift */; };
D70E9E0A2901AECF00A3C634 /* Remote.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC7228EB5EC0008B3BBC /* Remote.swift */; };
D70E9E0B2901AED400A3C634 /* Remotes.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC7328EB5EC0008B3BBC /* Remotes.swift */; };
D70E9E0C2901AEDA00A3C634 /* Repository+Lookup.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC8728EB5EC3008B3BBC /* Repository+Lookup.swift */; };
D70E9E0D2901AEDA00A3C634 /* Repository+Commit.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC8828EB5EC3008B3BBC /* Repository+Commit.swift */; };
D70E9E0E2901AEDA00A3C634 /* Repository+Open.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC8628EB5EC3008B3BBC /* Repository+Open.swift */; };
D70E9E0F2901AEDA00A3C634 /* Repository.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC8528EB5EC3008B3BBC /* Repository.swift */; };
D70E9E102901AEDA00A3C634 /* RepositoryManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC8428EB5EC3008B3BBC /* RepositoryManager.swift */; };
D70E9E112901AEE100A3C634 /* RevisionIterator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC6828EB5EBF008B3BBC /* RevisionIterator.swift */; };
D70E9E122901AEE100A3C634 /* FileHistoryIterator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC6928EB5EBF008B3BBC /* FileHistoryIterator.swift */; };
D70E9E132901AEE600A3C634 /* Statuses.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC7528EB5EC1008B3BBC /* Statuses.swift */; };
D70E9E142901AEEB00A3C634 /* StatusIterator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC7728EB5EC1008B3BBC /* StatusIterator.swift */; };
D70E9E152901AEEB00A3C634 /* Status.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC7628EB5EC1008B3BBC /* Status.swift */; };
D70E9E162901AEF300A3C634 /* TagIterator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC6428EB5EBF008B3BBC /* TagIterator.swift */; };
D70E9E172901AEF300A3C634 /* Tags.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC6528EB5EBF008B3BBC /* Tags.swift */; };
D70E9E182901AEF300A3C634 /* Tag.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC6628EB5EBF008B3BBC /* Tag.swift */; };
D70E9E192901AEF900A3C634 /* TreeEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC8128EB5EC2008B3BBC /* TreeEntry.swift */; };
D70E9E1A2901AEF900A3C634 /* Tree.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC8228EB5EC2008B3BBC /* Tree.swift */; };
D70F830428CE858E004818C5 /* Git in Frameworks */ = {isa = PBXBuildFile; productRef = D70F830328CE858E004818C5 /* Git */; };
D70F830628CE8596004818C5 /* Git in Frameworks */ = {isa = PBXBuildFile; productRef = D70F830528CE8596004818C5 /* Git */; };
D7104A64230BD8C500B6D8EE /* SortDirection.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7104A63230BD8C500B6D8EE /* SortDirection.swift */; };
D7104A65230BD8C500B6D8EE /* SortDirection.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7104A63230BD8C500B6D8EE /* SortDirection.swift */; };
D7104A67230BD8C500B6D8EE /* SortDirection.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7104A63230BD8C500B6D8EE /* SortDirection.swift */; };
D7104A68230BD8C500B6D8EE /* SortDirection.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7104A63230BD8C500B6D8EE /* SortDirection.swift */; };
D71354042042AFC800E3776F /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D71354032042AFC800E3776F /* SettingsViewController.swift */; };
D714496220C72D3500D7AD46 /* UIImage+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D714496120C72D3400D7AD46 /* UIImage+.swift */; };
D714749B279CE8EE001A8B29 /* MainNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D714749A279CE8EE001A8B29 /* MainNavigationController.swift */; };
D714749D279D7DBC001A8B29 /* SearchQuery.swift in Sources */ = {isa = PBXBuildFile; fileRef = D714749C279D7DBC001A8B29 /* SearchQuery.swift */; };
D7153DFD2285A93300A2C20F /* AboutWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7153DFC2285A93300A2C20F /* AboutWindowController.swift */; };
D7153DFE2285A93300A2C20F /* AboutWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7153DFC2285A93300A2C20F /* AboutWindowController.swift */; };
D7153E052285C09C00A2C20F /* AboutViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7153E042285C09C00A2C20F /* AboutViewController.swift */; };
D7153E062285C09C00A2C20F /* AboutViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7153E042285C09C00A2C20F /* AboutViewController.swift */; };
D7153E092285EC6100A2C20F /* TitleTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7153E082285EC6100A2C20F /* TitleTextField.swift */; };
D7153E0A2285EC6100A2C20F /* TitleTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7153E082285EC6100A2C20F /* TitleTextField.swift */; };
D7163D2F24E81B5C00B1FC05 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D7163D2E24E81B5C00B1FC05 /* Main.storyboard */; };
D7163D3424E81D9900B1FC05 /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D7163D3324E81D9900B1FC05 /* MainInterface.storyboard */; };
D7166F541F32F75E001A883F /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D7793C781F211C6000CA39B7 /* Main.storyboard */; };
D7170C1D20F8565B001DDB36 /* FileSystemEventManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7170C1C20F8565B001DDB36 /* FileSystemEventManager.swift */; };
D7170C1E20F8565B001DDB36 /* FileSystemEventManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7170C1C20F8565B001DDB36 /* FileSystemEventManager.swift */; };
D71760932826CAC4009794D8 /* MPreviewView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D730829123084340003185D1 /* MPreviewView.swift */; };
D7194B872023863A0062F1E3 /* ImagesProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D777D7802009115C00D86B33 /* ImagesProcessor.swift */; };
D71AA0222143A4A8004AFD2A /* MoveViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D71AA0212143A4A8004AFD2A /* MoveViewController.swift */; };
D71B9D7A2867027000D2F323 /* NoteViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D71B9D792867027000D2F323 /* NoteViewController.swift */; };
D71B9D7B2867027000D2F323 /* NoteViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D71B9D792867027000D2F323 /* NoteViewController.swift */; };
D71B9D822868658100D2F323 /* EditorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D71B9D812868658100D2F323 /* EditorViewController.swift */; };
D71B9D832868658100D2F323 /* EditorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D71B9D812868658100D2F323 /* EditorViewController.swift */; };
D71B9D862868BF7F00D2F323 /* TextStorageProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D71B9D852868BF7F00D2F323 /* TextStorageProcessor.swift */; };
D71B9D872868BF7F00D2F323 /* TextStorageProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D71B9D852868BF7F00D2F323 /* TextStorageProcessor.swift */; };
D71B9D892868BF7F00D2F323 /* TextStorageProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D71B9D852868BF7F00D2F323 /* TextStorageProcessor.swift */; };
D71C4A4E1F520F1B00EBA30B /* MPreview.bundle in Resources */ = {isa = PBXBuildFile; fileRef = D71C4A4D1F520F0E00EBA30B /* MPreview.bundle */; };
D71FD21F2101B2D5008BEFA1 /* NoteAttachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7038E2520FB24E000A54E69 /* NoteAttachment.swift */; };
D71FD2252101CFD0008BEFA1 /* UITextView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D71FD2242101CFD0008BEFA1 /* UITextView+.swift */; };
D720240F22A9412B000A7691 /* Markdown.icns in Resources */ = {isa = PBXBuildFile; fileRef = D720240922A9412B000A7691 /* Markdown.icns */; };
D720241022A9412B000A7691 /* Markdown.icns in Resources */ = {isa = PBXBuildFile; fileRef = D720240922A9412B000A7691 /* Markdown.icns */; };
D720241222A9412B000A7691 /* Text.icns in Resources */ = {isa = PBXBuildFile; fileRef = D720240A22A9412B000A7691 /* Text.icns */; };
D720241322A9412B000A7691 /* Text.icns in Resources */ = {isa = PBXBuildFile; fileRef = D720240A22A9412B000A7691 /* Text.icns */; };
D720241522A9412B000A7691 /* TextBundle.icns in Resources */ = {isa = PBXBuildFile; fileRef = D720240B22A9412B000A7691 /* TextBundle.icns */; };
D720241622A9412B000A7691 /* TextBundle.icns in Resources */ = {isa = PBXBuildFile; fileRef = D720240B22A9412B000A7691 /* TextBundle.icns */; };
D720241922A941A3000A7691 /* EncryptedTextPack.icns in Resources */ = {isa = PBXBuildFile; fileRef = D720241822A941A3000A7691 /* EncryptedTextPack.icns */; };
D720241A22A941A3000A7691 /* EncryptedTextPack.icns in Resources */ = {isa = PBXBuildFile; fileRef = D720241822A941A3000A7691 /* EncryptedTextPack.icns */; };
D72682AA29BE8E2000F6E961 /* RepositoryAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = D72682A929BE8E1F00F6E961 /* RepositoryAction.swift */; };
D72682AB29BE8E2000F6E961 /* RepositoryAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = D72682A929BE8E1F00F6E961 /* RepositoryAction.swift */; };
D72682AD29BE8E2000F6E961 /* RepositoryAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = D72682A929BE8E1F00F6E961 /* RepositoryAction.swift */; };
D72682AE29BE8E2100F6E961 /* RepositoryAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = D72682A929BE8E1F00F6E961 /* RepositoryAction.swift */; };
D726DE8A287ACC1E00F8406C /* NSWindow+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D726DE89287ACC1E00F8406C /* NSWindow+.swift */; };
D726DE8B287ACC1E00F8406C /* NSWindow+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D726DE89287ACC1E00F8406C /* NSWindow+.swift */; };
D72DAF0829B27D75001243BB /* ProjectSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = D72DAF0729B27D75001243BB /* ProjectSettings.swift */; };
D72DAF0929B27D75001243BB /* ProjectSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = D72DAF0729B27D75001243BB /* ProjectSettings.swift */; };
D72DAF0B29B27D75001243BB /* ProjectSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = D72DAF0729B27D75001243BB /* ProjectSettings.swift */; };
D72DAF0C29B27D75001243BB /* ProjectSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = D72DAF0729B27D75001243BB /* ProjectSettings.swift */; };
D730829223084340003185D1 /* MPreviewView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D730829123084340003185D1 /* MPreviewView.swift */; };
D730829323084340003185D1 /* MPreviewView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D730829123084340003185D1 /* MPreviewView.swift */; };
D730BD27222BF30700E69C93 /* KeychainConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = D730BD26222BF30700E69C93 /* KeychainConfiguration.swift */; };
D730BD28222BF30700E69C93 /* KeychainConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = D730BD26222BF30700E69C93 /* KeychainConfiguration.swift */; };
D730BD2A222BF32A00E69C93 /* KeychainPasswordItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D730BD29222BF32A00E69C93 /* KeychainPasswordItem.swift */; };
D730BD2B222BF32A00E69C93 /* KeychainPasswordItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D730BD29222BF32A00E69C93 /* KeychainPasswordItem.swift */; };
D730BD2E222DABA100E69C93 /* NoteContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D730BD2D222DABA100E69C93 /* NoteContainer.swift */; };
D730BD2F222DABA100E69C93 /* NoteContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D730BD2D222DABA100E69C93 /* NoteContainer.swift */; };
D730BD30222DABA100E69C93 /* NoteContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D730BD2D222DABA100E69C93 /* NoteContainer.swift */; };
D730BD31222DABA100E69C93 /* NoteContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D730BD2D222DABA100E69C93 /* NoteContainer.swift */; };
D730BD35222DB11E00E69C93 /* TextBundleInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D730BD34222DB11E00E69C93 /* TextBundleInfo.swift */; };
D730BD36222DB11E00E69C93 /* TextBundleInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D730BD34222DB11E00E69C93 /* TextBundleInfo.swift */; };
D730BD37222DB11E00E69C93 /* TextBundleInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D730BD34222DB11E00E69C93 /* TextBundleInfo.swift */; };
D730BD38222DB11E00E69C93 /* TextBundleInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D730BD34222DB11E00E69C93 /* TextBundleInfo.swift */; };
D730BD3C222DB9FC00E69C93 /* NameHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = D730BD3B222DB9FC00E69C93 /* NameHelper.swift */; };
D730BD3D222DB9FC00E69C93 /* NameHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = D730BD3B222DB9FC00E69C93 /* NameHelper.swift */; };
D730BD3E222DB9FC00E69C93 /* NameHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = D730BD3B222DB9FC00E69C93 /* NameHelper.swift */; };
D730BD3F222DB9FC00E69C93 /* NameHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = D730BD3B222DB9FC00E69C93 /* NameHelper.swift */; };
D730BD45223510A700E69C93 /* KeychainPasswordItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D730BD29222BF32A00E69C93 /* KeychainPasswordItem.swift */; };
D730BD46223510A900E69C93 /* KeychainConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = D730BD26222BF30700E69C93 /* KeychainConfiguration.swift */; };
D730BD5A223BFEB200E69C93 /* RuntimeError.swift in Sources */ = {isa = PBXBuildFile; fileRef = D730BD59223BFEB200E69C93 /* RuntimeError.swift */; };
D730BD5B223BFEB200E69C93 /* RuntimeError.swift in Sources */ = {isa = PBXBuildFile; fileRef = D730BD59223BFEB200E69C93 /* RuntimeError.swift */; };
D730BD5C223BFEB200E69C93 /* RuntimeError.swift in Sources */ = {isa = PBXBuildFile; fileRef = D730BD59223BFEB200E69C93 /* RuntimeError.swift */; };
D7315ECF215ECF3000AB49D4 /* EditorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7315ECE215ECF3000AB49D4 /* EditorView.swift */; };
D7315ED0215ECF3000AB49D4 /* EditorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7315ECE215ECF3000AB49D4 /* EditorView.swift */; };
D7315ED2215ED15500AB49D4 /* SidebarSplitView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7315ED1215ED15500AB49D4 /* SidebarSplitView.swift */; };
D7315ED3215ED15500AB49D4 /* SidebarSplitView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7315ED1215ED15500AB49D4 /* SidebarSplitView.swift */; };
D7315ED5215ED95600AB49D4 /* NSAppearance+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7315ED4215ED95600AB49D4 /* NSAppearance+.swift */; };
D7315ED6215ED95600AB49D4 /* NSAppearance+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7315ED4215ED95600AB49D4 /* NSAppearance+.swift */; };
D73290BA2099F0AB0003F647 /* UndoData.swift in Sources */ = {isa = PBXBuildFile; fileRef = D78678CA2093AE10001A6620 /* UndoData.swift */; };
D735E5BD1F2EF66000173215 /* NoteCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D735E5BC1F2EF66000173215 /* NoteCellView.swift */; };
D735E5BF1F2F001500173215 /* NoteRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D735E5BE1F2F001500173215 /* NoteRowView.swift */; };
D73673A820D10CF2000BA61D /* CloudDriveManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73673A720D10CF2000BA61D /* CloudDriveManager.swift */; };
D736DDA927B5DD370012ED70 /* EditorSelectionRect.swift in Sources */ = {isa = PBXBuildFile; fileRef = D736DDA827B5DD370012ED70 /* EditorSelectionRect.swift */; };
D736DDAB27BABFFB0012ED70 /* RevisionsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D736DDAA27BABFF80012ED70 /* RevisionsViewController.swift */; };
D736DDAD27BAC7940012ED70 /* Note+History.swift in Sources */ = {isa = PBXBuildFile; fileRef = D736DDAC27BAC7940012ED70 /* Note+History.swift */; };
D73794BF2336642500E75A28 /* (null) in Sources */ = {isa = PBXBuildFile; };
D73794C123366F5200E75A28 /* ImageScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73794C023366F5200E75A28 /* ImageScrollView.swift */; };
D738356D2242871400B260DD /* MasterPasswordViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D738356C2242871400B260DD /* MasterPasswordViewController.swift */; };
D738356E2242871400B260DD /* MasterPasswordViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D738356C2242871400B260DD /* MasterPasswordViewController.swift */; };
D73B3135298FBF4400F46144 /* GitViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73B3134298FBF4400F46144 /* GitViewController.swift */; };
D73BCC8C28EB5EC3008B3BBC /* Commit.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC5428EB5EBE008B3BBC /* Commit.swift */; };
D73BCC8D28EB5EC3008B3BBC /* Commit.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC5428EB5EBE008B3BBC /* Commit.swift */; };
D73BCC8F28EB5EC3008B3BBC /* Branch.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC5628EB5EBE008B3BBC /* Branch.swift */; };
D73BCC9028EB5EC3008B3BBC /* Branch.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC5628EB5EBE008B3BBC /* Branch.swift */; };
D73BCC9228EB5EC3008B3BBC /* Branches.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC5728EB5EBE008B3BBC /* Branches.swift */; };
D73BCC9328EB5EC3008B3BBC /* Branches.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC5728EB5EBE008B3BBC /* Branches.swift */; };
D73BCC9528EB5EC3008B3BBC /* BranchesIterator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC5828EB5EBE008B3BBC /* BranchesIterator.swift */; };
D73BCC9628EB5EC3008B3BBC /* BranchesIterator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC5828EB5EBE008B3BBC /* BranchesIterator.swift */; };
D73BCC9828EB5EC3008B3BBC /* Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC5A28EB5EBE008B3BBC /* Strings.swift */; };
D73BCC9928EB5EC3008B3BBC /* Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC5A28EB5EBE008B3BBC /* Strings.swift */; };
D73BCC9B28EB5EC3008B3BBC /* ConfigManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC5B28EB5EBE008B3BBC /* ConfigManager.swift */; };
D73BCC9C28EB5EC3008B3BBC /* ConfigManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC5B28EB5EBE008B3BBC /* ConfigManager.swift */; };
D73BCC9E28EB5EC3008B3BBC /* Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC5C28EB5EBE008B3BBC /* Error.swift */; };
D73BCC9F28EB5EC3008B3BBC /* Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC5C28EB5EBE008B3BBC /* Error.swift */; };
D73BCCA128EB5EC3008B3BBC /* Wrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC5D28EB5EBE008B3BBC /* Wrapper.swift */; };
D73BCCA228EB5EC3008B3BBC /* Wrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC5D28EB5EBE008B3BBC /* Wrapper.swift */; };
D73BCCA428EB5EC3008B3BBC /* Progress.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC5E28EB5EBE008B3BBC /* Progress.swift */; };
D73BCCA528EB5EC3008B3BBC /* Progress.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC5E28EB5EBE008B3BBC /* Progress.swift */; };
D73BCCA728EB5EC3008B3BBC /* Blob.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC5F28EB5EBE008B3BBC /* Blob.swift */; };
D73BCCA828EB5EC3008B3BBC /* Blob.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC5F28EB5EBE008B3BBC /* Blob.swift */; };
D73BCCAA28EB5EC3008B3BBC /* OID.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC6028EB5EBF008B3BBC /* OID.swift */; };
D73BCCAB28EB5EC3008B3BBC /* OID.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC6028EB5EBF008B3BBC /* OID.swift */; };
D73BCCAD28EB5EC3008B3BBC /* Signature.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC6128EB5EBF008B3BBC /* Signature.swift */; };
D73BCCAE28EB5EC3008B3BBC /* Signature.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC6128EB5EBF008B3BBC /* Signature.swift */; };
D73BCCB028EB5EC3008B3BBC /* Object.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC6228EB5EBF008B3BBC /* Object.swift */; };
D73BCCB128EB5EC3008B3BBC /* Object.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC6228EB5EBF008B3BBC /* Object.swift */; };
D73BCCB328EB5EC3008B3BBC /* TagIterator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC6428EB5EBF008B3BBC /* TagIterator.swift */; };
D73BCCB428EB5EC3008B3BBC /* TagIterator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC6428EB5EBF008B3BBC /* TagIterator.swift */; };
D73BCCB628EB5EC3008B3BBC /* Tags.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC6528EB5EBF008B3BBC /* Tags.swift */; };
D73BCCB728EB5EC3008B3BBC /* Tags.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC6528EB5EBF008B3BBC /* Tags.swift */; };
D73BCCB928EB5EC3008B3BBC /* Tag.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC6628EB5EBF008B3BBC /* Tag.swift */; };
D73BCCBA28EB5EC3008B3BBC /* Tag.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC6628EB5EBF008B3BBC /* Tag.swift */; };
D73BCCBC28EB5EC3008B3BBC /* RevisionIterator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC6828EB5EBF008B3BBC /* RevisionIterator.swift */; };
D73BCCBD28EB5EC3008B3BBC /* RevisionIterator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC6828EB5EBF008B3BBC /* RevisionIterator.swift */; };
D73BCCBF28EB5EC3008B3BBC /* FileHistoryIterator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC6928EB5EBF008B3BBC /* FileHistoryIterator.swift */; };
D73BCCC028EB5EC3008B3BBC /* FileHistoryIterator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC6928EB5EBF008B3BBC /* FileHistoryIterator.swift */; };
D73BCCC228EB5EC3008B3BBC /* DiffEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC6B28EB5EC0008B3BBC /* DiffEntry.swift */; };
D73BCCC328EB5EC3008B3BBC /* DiffEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC6B28EB5EC0008B3BBC /* DiffEntry.swift */; };
D73BCCC528EB5EC4008B3BBC /* Diff.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC6C28EB5EC0008B3BBC /* Diff.swift */; };
D73BCCC628EB5EC4008B3BBC /* Diff.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC6C28EB5EC0008B3BBC /* Diff.swift */; };
D73BCCC828EB5EC4008B3BBC /* KeyAuthentication.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC6E28EB5EC0008B3BBC /* KeyAuthentication.swift */; };
D73BCCC928EB5EC4008B3BBC /* KeyAuthentication.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC6E28EB5EC0008B3BBC /* KeyAuthentication.swift */; };
D73BCCCB28EB5EC4008B3BBC /* Authentication.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC6F28EB5EC0008B3BBC /* Authentication.swift */; };
D73BCCCC28EB5EC4008B3BBC /* Authentication.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC6F28EB5EC0008B3BBC /* Authentication.swift */; };
D73BCCCE28EB5EC4008B3BBC /* PasswordAuthentication.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC7028EB5EC0008B3BBC /* PasswordAuthentication.swift */; };
D73BCCCF28EB5EC4008B3BBC /* PasswordAuthentication.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC7028EB5EC0008B3BBC /* PasswordAuthentication.swift */; };
D73BCCD128EB5EC4008B3BBC /* Remote.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC7228EB5EC0008B3BBC /* Remote.swift */; };
D73BCCD228EB5EC4008B3BBC /* Remote.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC7228EB5EC0008B3BBC /* Remote.swift */; };
D73BCCD428EB5EC4008B3BBC /* Remotes.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC7328EB5EC0008B3BBC /* Remotes.swift */; };
D73BCCD528EB5EC4008B3BBC /* Remotes.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC7328EB5EC0008B3BBC /* Remotes.swift */; };
D73BCCD728EB5EC4008B3BBC /* Statuses.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC7528EB5EC1008B3BBC /* Statuses.swift */; };
D73BCCD828EB5EC4008B3BBC /* Statuses.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC7528EB5EC1008B3BBC /* Statuses.swift */; };
D73BCCDA28EB5EC4008B3BBC /* Status.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC7628EB5EC1008B3BBC /* Status.swift */; };
D73BCCDB28EB5EC4008B3BBC /* Status.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC7628EB5EC1008B3BBC /* Status.swift */; };
D73BCCDD28EB5EC4008B3BBC /* StatusIterator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC7728EB5EC1008B3BBC /* StatusIterator.swift */; };
D73BCCDE28EB5EC4008B3BBC /* StatusIterator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC7728EB5EC1008B3BBC /* StatusIterator.swift */; };
D73BCCE028EB5EC4008B3BBC /* Index.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC7928EB5EC1008B3BBC /* Index.swift */; };
D73BCCE128EB5EC4008B3BBC /* Index.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC7928EB5EC1008B3BBC /* Index.swift */; };
D73BCCE328EB5EC4008B3BBC /* Index+Commit.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC7A28EB5EC1008B3BBC /* Index+Commit.swift */; };
D73BCCE428EB5EC4008B3BBC /* Index+Commit.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC7A28EB5EC1008B3BBC /* Index+Commit.swift */; };
D73BCCE628EB5EC4008B3BBC /* Index+Files.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC7B28EB5EC1008B3BBC /* Index+Files.swift */; };
D73BCCE728EB5EC4008B3BBC /* Index+Files.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC7B28EB5EC1008B3BBC /* Index+Files.swift */; };
D73BCCE928EB5EC4008B3BBC /* Head+Checkout.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC7D28EB5EC2008B3BBC /* Head+Checkout.swift */; };
D73BCCEA28EB5EC4008B3BBC /* Head+Checkout.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC7D28EB5EC2008B3BBC /* Head+Checkout.swift */; };
D73BCCEC28EB5EC4008B3BBC /* Head.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC7E28EB5EC2008B3BBC /* Head.swift */; };
D73BCCED28EB5EC4008B3BBC /* Head.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC7E28EB5EC2008B3BBC /* Head.swift */; };
D73BCCEF28EB5EC4008B3BBC /* Head+Merge.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC7F28EB5EC2008B3BBC /* Head+Merge.swift */; };
D73BCCF028EB5EC4008B3BBC /* Head+Merge.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC7F28EB5EC2008B3BBC /* Head+Merge.swift */; };
D73BCCF228EB5EC4008B3BBC /* TreeEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC8128EB5EC2008B3BBC /* TreeEntry.swift */; };
D73BCCF328EB5EC4008B3BBC /* TreeEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC8128EB5EC2008B3BBC /* TreeEntry.swift */; };
D73BCCF528EB5EC4008B3BBC /* Tree.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC8228EB5EC2008B3BBC /* Tree.swift */; };
D73BCCF628EB5EC4008B3BBC /* Tree.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC8228EB5EC2008B3BBC /* Tree.swift */; };
D73BCCF828EB5EC4008B3BBC /* RepositoryManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC8428EB5EC3008B3BBC /* RepositoryManager.swift */; };
D73BCCF928EB5EC4008B3BBC /* RepositoryManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC8428EB5EC3008B3BBC /* RepositoryManager.swift */; };
D73BCCFB28EB5EC4008B3BBC /* Repository.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC8528EB5EC3008B3BBC /* Repository.swift */; };
D73BCCFC28EB5EC4008B3BBC /* Repository.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC8528EB5EC3008B3BBC /* Repository.swift */; };
D73BCCFE28EB5EC4008B3BBC /* Repository+Open.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC8628EB5EC3008B3BBC /* Repository+Open.swift */; };
D73BCCFF28EB5EC4008B3BBC /* Repository+Open.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC8628EB5EC3008B3BBC /* Repository+Open.swift */; };
D73BCD0128EB5EC4008B3BBC /* Repository+Lookup.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC8728EB5EC3008B3BBC /* Repository+Lookup.swift */; };
D73BCD0228EB5EC4008B3BBC /* Repository+Lookup.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC8728EB5EC3008B3BBC /* Repository+Lookup.swift */; };
D73BCD0428EB5EC4008B3BBC /* Repository+Commit.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC8828EB5EC3008B3BBC /* Repository+Commit.swift */; };
D73BCD0528EB5EC4008B3BBC /* Repository+Commit.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC8828EB5EC3008B3BBC /* Repository+Commit.swift */; };
D73BCD0728EB5EC4008B3BBC /* Reference.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC8A28EB5EC3008B3BBC /* Reference.swift */; };
D73BCD0828EB5EC4008B3BBC /* Reference.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC8A28EB5EC3008B3BBC /* Reference.swift */; };
D73BCD0A28EB5EC4008B3BBC /* Reference+Target.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC8B28EB5EC3008B3BBC /* Reference+Target.swift */; };
D73BCD0B28EB5EC4008B3BBC /* Reference+Target.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC8B28EB5EC3008B3BBC /* Reference+Target.swift */; };
D73FABDA207F2EB600A98483 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D7465F27207F2CD600E46A52 /* Images.xcassets */; };
D73FAE9F21553CAA0058BE61 /* UIApplication+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73FAE9E21553CAA0058BE61 /* UIApplication+.swift */; };
D74112281FABA21B00AB619A /* MainWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = D74112271FABA21B00AB619A /* MainWindow.swift */; };
D74112291FABA29100AB619A /* MainWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = D74112271FABA21B00AB619A /* MainWindow.swift */; };
D743FB5324CD72B0003A8913 /* SettingsFilesNaming.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7BAC62E249D11F8008D29AA /* SettingsFilesNaming.swift */; };
D743FB5424CD72B1003A8913 /* SettingsFilesNaming.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7BAC62E249D11F8008D29AA /* SettingsFilesNaming.swift */; };
D7465F28207F2CD600E46A52 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D7465F27207F2CD600E46A52 /* Images.xcassets */; };
D7470D072170E890006B2A92 /* NSTextStorage++.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7470D062170E890006B2A92 /* NSTextStorage++.swift */; };
D7470D082170E890006B2A92 /* NSTextStorage++.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7470D062170E890006B2A92 /* NSTextStorage++.swift */; };
D7470D092170E890006B2A92 /* NSTextStorage++.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7470D062170E890006B2A92 /* NSTextStorage++.swift */; };
D7487F922173503C00D09383 /* AttributedBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = D74B7B642137D3A1007F5331 /* AttributedBox.swift */; };
D7487F932173503C00D09383 /* AttributedBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = D74B7B642137D3A1007F5331 /* AttributedBox.swift */; };
D7487FD721738A1800D09383 /* NSImage+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7487FD5217389F800D09383 /* NSImage+.swift */; };
D7487FD821738A1900D09383 /* NSImage+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7487FD5217389F800D09383 /* NSImage+.swift */; };
D7487FEB2174E62A00D09383 /* NSAttributedStringKey+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7487FE82174E5CB00D09383 /* NSAttributedStringKey+.swift */; };
D7487FEC2174E62B00D09383 /* NSAttributedStringKey+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7487FE82174E5CB00D09383 /* NSAttributedStringKey+.swift */; };
D7487FED2174E62B00D09383 /* NSAttributedStringKey+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7487FE82174E5CB00D09383 /* NSAttributedStringKey+.swift */; };
D74B7B672137D3A1007F5331 /* AttributedBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = D74B7B642137D3A1007F5331 /* AttributedBox.swift */; };
D74B7B692137EFA9007F5331 /* SingleTouchDownGestureRecognizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D74B7B682137EFA9007F5331 /* SingleTouchDownGestureRecognizer.swift */; };
D74D479F256DF2EB00D97647 /* FSNTextAttachmentCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D74D479E256DF2EB00D97647 /* FSNTextAttachmentCell.swift */; };
D74D47A0256DF2EB00D97647 /* FSNTextAttachmentCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D74D479E256DF2EB00D97647 /* FSNTextAttachmentCell.swift */; };
D74DFBAC21661BA300F67D64 /* Date+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D76E10C0215A55CE0017F4A3 /* Date+.swift */; };
D74DFBAD21661BA400F67D64 /* Date+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D76E10C0215A55CE0017F4A3 /* Date+.swift */; };
D750345E285F817D00086424 /* String+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F13BB2920FEDE230005E120 /* String+.swift */; };
D750345F285F81F300086424 /* URL+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F13BB2A20FEDE230005E120 /* URL+.swift */; };
D7503460285F827800086424 /* DateFormatter+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F13BB2820FEDE230005E120 /* DateFormatter+.swift */; };
D7508FC81F337E850047AB76 /* SearchTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7508FC71F337E850047AB76 /* SearchTextField.swift */; };
D7508FCE1F3438540047AB76 /* PrefsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7508FCD1F3438540047AB76 /* PrefsViewController.swift */; };
D752D80823454750006842F9 /* NSTextAttachment+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D752D80723454750006842F9 /* NSTextAttachment+.swift */; };
D752D80923454750006842F9 /* NSTextAttachment+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D752D80723454750006842F9 /* NSTextAttachment+.swift */; };
D752D80B23454750006842F9 /* NSTextAttachment+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D752D80723454750006842F9 /* NSTextAttachment+.swift */; };
D75627CE26D1165A000AF6EA /* ImageFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = D75627CD26D1165A000AF6EA /* ImageFormat.swift */; };
D75627CF26D1165A000AF6EA /* ImageFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = D75627CD26D1165A000AF6EA /* ImageFormat.swift */; };
D75627D126D1165A000AF6EA /* ImageFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = D75627CD26D1165A000AF6EA /* ImageFormat.swift */; };
D75627D226D1165A000AF6EA /* ImageFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = D75627CD26D1165A000AF6EA /* ImageFormat.swift */; };
D75629B127D4DB7E00F55588 /* CodeFontViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D75629B027D4DB7E00F55588 /* CodeFontViewController.swift */; };
D75629B327D4DE9F00F55588 /* CodeThemeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D75629B227D4DE9F00F55588 /* CodeThemeViewController.swift */; };
D75629B527D5036D00F55588 /* SortByViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D75629B427D5036D00F55588 /* SortByViewController.swift */; };
D75629B727D53EB100F55588 /* ThanksViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D75629B627D53EB100F55588 /* ThanksViewController.swift */; };
D75A34E527D7CD440085438F /* SidebarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D75A34E427D7CD440085438F /* SidebarViewController.swift */; };
D75EE7F72078B22D0055F159 /* SidebarItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D75EE7F62078B22D0055F159 /* SidebarItem.swift */; };
D75EE7F82078B22D0055F159 /* SidebarItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D75EE7F62078B22D0055F159 /* SidebarItem.swift */; };
D75EE7FA2078B3C00055F159 /* Sidebar.swift in Sources */ = {isa = PBXBuildFile; fileRef = D75EE7F92078B3C00055F159 /* Sidebar.swift */; };
D75EE7FB2078B3C00055F159 /* Sidebar.swift in Sources */ = {isa = PBXBuildFile; fileRef = D75EE7F92078B3C00055F159 /* Sidebar.swift */; };
D75EE7FD2078C5460055F159 /* SidebarCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D75EE7FC2078C5460055F159 /* SidebarCellView.swift */; };
D75EE7FE2078C5460055F159 /* SidebarCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D75EE7FC2078C5460055F159 /* SidebarCellView.swift */; };
D75EE8002078E0C60055F159 /* SidebarItemType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D75EE7FF2078E0C60055F159 /* SidebarItemType.swift */; };
D75EE8012078E0C60055F159 /* SidebarItemType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D75EE7FF2078E0C60055F159 /* SidebarItemType.swift */; };
D75F1DF1206D660D00F70B28 /* MPreview.bundle in Resources */ = {isa = PBXBuildFile; fileRef = D71C4A4D1F520F0E00EBA30B /* MPreview.bundle */; };
D75F3339205EC34800CC887E /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D75F3338205EC34800CC887E /* ShareViewController.swift */; };
D75F3340205EC34800CC887E /* FSNotes iOS Share Extension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = D75F3336205EC34800CC887E /* FSNotes iOS Share Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
D76025B2204EEF64000B9F59 /* TextFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = D76025B1204EEF64000B9F59 /* TextFormatter.swift */; };
D76025B3204EEF64000B9F59 /* TextFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = D76025B1204EEF64000B9F59 /* TextFormatter.swift */; };
D76025B4204EEF64000B9F59 /* TextFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = D76025B1204EEF64000B9F59 /* TextFormatter.swift */; };
D76447DC1F3A4F0700965F01 /* UserDefaultsManagement.swift in Sources */ = {isa = PBXBuildFile; fileRef = D76447DB1F3A4F0700965F01 /* UserDefaultsManagement.swift */; };
D7679376201F0BFD000F7BBF /* SortBy.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7679375201F0BFD000F7BBF /* SortBy.swift */; };
D7679377201F0BFD000F7BBF /* SortBy.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7679375201F0BFD000F7BBF /* SortBy.swift */; };
D7679389201F21F5000F7BBF /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7679388201F21F5000F7BBF /* AppDelegate.swift */; };
D767938B201F21F5000F7BBF /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D767938A201F21F5000F7BBF /* ViewController.swift */; };
D7680FB225D02B2C00810DA8 /* FileManager+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7680FB125D02B2C00810DA8 /* FileManager+.swift */; };
D7680FB325D02B2C00810DA8 /* FileManager+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7680FB125D02B2C00810DA8 /* FileManager+.swift */; };
D7680FB525D02B2C00810DA8 /* FileManager+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7680FB125D02B2C00810DA8 /* FileManager+.swift */; };
D7680FB625D02B2C00810DA8 /* FileManager+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7680FB125D02B2C00810DA8 /* FileManager+.swift */; };
D768D758245E86670028F344 /* NSAttributedString+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D768D754245E854D0028F344 /* NSAttributedString+.swift */; };
D768D759245E86680028F344 /* NSAttributedString+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D768D754245E854D0028F344 /* NSAttributedString+.swift */; };
D768D75A245E86690028F344 /* NSAttributedString+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D768D754245E854D0028F344 /* NSAttributedString+.swift */; };
D768D75C245ED6470028F344 /* VerticallyAlignedTextFieldCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D768D75B245ED6470028F344 /* VerticallyAlignedTextFieldCell.swift */; };
D768D75D245ED6470028F344 /* VerticallyAlignedTextFieldCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D768D75B245ED6470028F344 /* VerticallyAlignedTextFieldCell.swift */; };
D76E10C1215A55CE0017F4A3 /* Date+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D76E10C0215A55CE0017F4A3 /* Date+.swift */; };
D76F3682272563EC00D1FFB4 /* NSAttributedString+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D768D754245E854D0028F344 /* NSAttributedString+.swift */; };
D77015822C972B7500CFF0E8 /* SettingsTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D77015812C972B6D00CFF0E8 /* SettingsTableViewCell.swift */; };
D771E96F28EDFBF600CD4871 /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = D771E96E28EDFBF600CD4871 /* Errors.swift */; };
D771E97028EDFBF600CD4871 /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = D771E96E28EDFBF600CD4871 /* Errors.swift */; };
D772C8842217362C007E440B /* ViewController+Print.swift in Sources */ = {isa = PBXBuildFile; fileRef = D772C8832217362C007E440B /* ViewController+Print.swift */; };
D772C8852217362C007E440B /* ViewController+Print.swift in Sources */ = {isa = PBXBuildFile; fileRef = D772C8832217362C007E440B /* ViewController+Print.swift */; };
D7737393223D59CF00154B9E /* KeychainConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = D730BD26222BF30700E69C93 /* KeychainConfiguration.swift */; };
D7737394223D59D300154B9E /* KeychainPasswordItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D730BD29222BF32A00E69C93 /* KeychainPasswordItem.swift */; };
D773DE801F36F45900A39C9F /* SandboxBookmark.swift in Sources */ = {isa = PBXBuildFile; fileRef = D773DE7F1F36F45900A39C9F /* SandboxBookmark.swift */; };
D7767C7F234E47B9006A0716 /* Markdown.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F7136ED23490CBF004DFA6E /* Markdown.swift */; };
D777D7812009115C00D86B33 /* ImagesProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D777D7802009115C00D86B33 /* ImagesProcessor.swift */; };
D777D782200912A400D86B33 /* ImagesProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D777D7802009115C00D86B33 /* ImagesProcessor.swift */; };
D7793C731F211C6000CA39B7 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7793C721F211C6000CA39B7 /* AppDelegate.swift */; };
D7793C751F211C6000CA39B7 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7793C741F211C6000CA39B7 /* ViewController.swift */; };
D779C7BB1F415C0300FADEE1 /* PrefsWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D779C7BA1F415BE300FADEE1 /* PrefsWindowController.swift */; };
D77A12372C469ACF001B388B /* SearchQuery.swift in Sources */ = {isa = PBXBuildFile; fileRef = D714749C279D7DBC001A8B29 /* SearchQuery.swift */; };
D77A12382C469AD0001B388B /* SearchQuery.swift in Sources */ = {isa = PBXBuildFile; fileRef = D714749C279D7DBC001A8B29 /* SearchQuery.swift */; };
D77A6F7F28B11496006A0353 /* PreferencesWebViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D77A6F7E28B11496006A0353 /* PreferencesWebViewController.swift */; };
D77A6F8028B11496006A0353 /* PreferencesWebViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D77A6F7E28B11496006A0353 /* PreferencesWebViewController.swift */; };
D77AD7FC27F9D1C90077BD45 /* Data+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D77AD7FB27F9D1C90077BD45 /* Data+.swift */; };
D77AD7FD27F9D1C90077BD45 /* Data+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D77AD7FB27F9D1C90077BD45 /* Data+.swift */; };
D77AD7FF27F9D1C90077BD45 /* Data+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D77AD7FB27F9D1C90077BD45 /* Data+.swift */; };
D77CC041216A608500582B97 /* EditorScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D77CC040216A608500582B97 /* EditorScrollView.swift */; };
D77CC042216A608500582B97 /* EditorScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D77CC040216A608500582B97 /* EditorScrollView.swift */; };
D77E0536246312B200AD7772 /* StorageType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D77E05282463124300AD7772 /* StorageType.swift */; };
D77E0537246312B300AD7772 /* StorageType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D77E05282463124300AD7772 /* StorageType.swift */; };
D77E0538246312B400AD7772 /* StorageType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D77E05282463124300AD7772 /* StorageType.swift */; };
D77E0539246312B400AD7772 /* StorageType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D77E05282463124300AD7772 /* StorageType.swift */; };
D77F41B32A0D48F500E2B7A2 /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D77F41B22A0D48F500E2B7A2 /* Launch Screen.storyboard */; };
D77F89DF28D38B5D00BECC87 /* ViewController+Web.swift in Sources */ = {isa = PBXBuildFile; fileRef = D77F89DE28D38B5D00BECC87 /* ViewController+Web.swift */; };
D77F89E028D38B5E00BECC87 /* ViewController+Web.swift in Sources */ = {isa = PBXBuildFile; fileRef = D77F89DE28D38B5D00BECC87 /* ViewController+Web.swift */; };
D78115632153B36C004FA1CA /* Buttons.swift in Sources */ = {isa = PBXBuildFile; fileRef = D78115622153B36C004FA1CA /* Buttons.swift */; };
D78115672153D4D9004FA1CA /* ProjectsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D78115662153D4D9004FA1CA /* ProjectsViewController.swift */; };
D781156B2153E05A004FA1CA /* ProjectSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D781156A2153E05A004FA1CA /* ProjectSettingsViewController.swift */; };
D783B505208A1BFD00328A41 /* EditorSplitView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D783B504208A1BFD00328A41 /* EditorSplitView.swift */; };
D783B506208A1BFD00328A41 /* EditorSplitView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D783B504208A1BFD00328A41 /* EditorSplitView.swift */; };
D785805C27A3483B000C1BAF /* FolderPopoverActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D785805B27A3483B000C1BAF /* FolderPopoverActions.swift */; };
D78678CB2093AE10001A6620 /* UndoData.swift in Sources */ = {isa = PBXBuildFile; fileRef = D78678CA2093AE10001A6620 /* UndoData.swift */; };
D78678CC2093AE10001A6620 /* UndoData.swift in Sources */ = {isa = PBXBuildFile; fileRef = D78678CA2093AE10001A6620 /* UndoData.swift */; };
D792297521A845B4005F468F /* ProjectSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D792297421A845B4005F468F /* ProjectSettingsViewController.swift */; };
D792297621A845B4005F468F /* ProjectSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D792297421A845B4005F468F /* ProjectSettingsViewController.swift */; };
D792DD8227A6C980006ADC01 /* FSParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = D792DD8127A6C980006ADC01 /* FSParser.swift */; };
D792DD8327A6C980006ADC01 /* FSParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = D792DD8127A6C980006ADC01 /* FSParser.swift */; };
D792DD8527A6C980006ADC01 /* FSParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = D792DD8127A6C980006ADC01 /* FSParser.swift */; };
D792DD8627A6C980006ADC01 /* FSParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = D792DD8127A6C980006ADC01 /* FSParser.swift */; };
D792DD9427A6D6F5006ADC01 /* String+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F13BB2920FEDE230005E120 /* String+.swift */; };
D792DD9627A6D71C006ADC01 /* String+Punycode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D792DD9527A6D71C006ADC01 /* String+Punycode.swift */; };
D792DD9727A6D71C006ADC01 /* String+Punycode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D792DD9527A6D71C006ADC01 /* String+Punycode.swift */; };
D792DD9927A6D71C006ADC01 /* String+Punycode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D792DD9527A6D71C006ADC01 /* String+Punycode.swift */; };
D794558E27C05743000C283F /* ProViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D794558D27C05743000C283F /* ProViewController.swift */; };
D794559A27C1B3F9000C283F /* ExternalViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D794559927C1B3F9000C283F /* ExternalViewController.swift */; };
D7958A3922ED512D00EDBDDC /* SandboxBookmark.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7958A3822ED512D00EDBDDC /* SandboxBookmark.swift */; };
D7958A3A22ED512D00EDBDDC /* SandboxBookmark.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7958A3822ED512D00EDBDDC /* SandboxBookmark.swift */; };
D79651B12517741400333AD4 /* ProgressState.swift in Sources */ = {isa = PBXBuildFile; fileRef = D79651B02517741400333AD4 /* ProgressState.swift */; };
D79651B22517741400333AD4 /* ProgressState.swift in Sources */ = {isa = PBXBuildFile; fileRef = D79651B02517741400333AD4 /* ProgressState.swift */; };
D79651B42517741400333AD4 /* ProgressState.swift in Sources */ = {isa = PBXBuildFile; fileRef = D79651B02517741400333AD4 /* ProgressState.swift */; };
D79651B52517741400333AD4 /* ProgressState.swift in Sources */ = {isa = PBXBuildFile; fileRef = D79651B02517741400333AD4 /* ProgressState.swift */; };
D796EB41251E127300CE5C80 /* Pasteboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = D796EB40251E127300CE5C80 /* Pasteboard.swift */; };
D796EB42251E127300CE5C80 /* Pasteboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = D796EB40251E127300CE5C80 /* Pasteboard.swift */; };
D797004C1F3DD10700BAD94D /* EditTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D797004B1F3DD10700BAD94D /* EditTextView.swift */; };
D79798A229C0FE6A00B9A878 /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D79798A129C0FE6A00B9A878 /* SettingsViewController.swift */; };
D79798A329C0FE6A00B9A878 /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D79798A129C0FE6A00B9A878 /* SettingsViewController.swift */; };
D79A13CD2A0E9C980037510B /* UIColor+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D79A13CC2A0E9C980037510B /* UIColor+.swift */; };
D79A13CE2A0E9C980037510B /* UIColor+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D79A13CC2A0E9C980037510B /* UIColor+.swift */; };
D79C26252872384C00CB70E6 /* EditorViewController+Sharing.swift in Sources */ = {isa = PBXBuildFile; fileRef = D79C26242872384C00CB70E6 /* EditorViewController+Sharing.swift */; };
D79C26262872384C00CB70E6 /* EditorViewController+Sharing.swift in Sources */ = {isa = PBXBuildFile; fileRef = D79C26242872384C00CB70E6 /* EditorViewController+Sharing.swift */; };
D79F92121FA8B9E2008C297E /* PreviewTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7CE196B1FA4BA5E004BF8EE /* PreviewTextField.swift */; };
D79FE8A21F77D04A00113CFD /* Note.swift in Sources */ = {isa = PBXBuildFile; fileRef = D79FE8A01F77D04A00113CFD /* Note.swift */; };
D7A415141F2FBDA00099B82C /* NotesTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7A415131F2FBDA00099B82C /* NotesTableView.swift */; };
D7A549C324DD9D3400537544 /* SettingsEditorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7A549C224DD9D3400537544 /* SettingsEditorViewController.swift */; };
D7A65C5920F11C38003E5ADC /* LanguageType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7A65C5820F11C38003E5ADC /* LanguageType.swift */; };
D7A65C5A20F11C38003E5ADC /* LanguageType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7A65C5820F11C38003E5ADC /* LanguageType.swift */; };
D7A9C1D62910784400905619 /* Project+Git.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7A9C1D52910784400905619 /* Project+Git.swift */; };
D7A9C1D72910784400905619 /* Project+Git.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7A9C1D52910784400905619 /* Project+Git.swift */; };
D7A9C1D92910784400905619 /* Project+Git.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7A9C1D52910784400905619 /* Project+Git.swift */; };
D7A9C1DB29107A0800905619 /* Git in Frameworks */ = {isa = PBXBuildFile; productRef = D7A9C1DA29107A0800905619 /* Git */; };
D7A9C1DC29107B7600905619 /* Reference+Target.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73BCC8B28EB5EC3008B3BBC /* Reference+Target.swift */; };
D7ADFD112066CF9400B531F9 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D7ADFD102066CF9400B531F9 /* CoreLocation.framework */; };
D7B13DBD2C64F445008EBCAA /* Printer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7B13DBC2C64F445008EBCAA /* Printer.swift */; };
D7B13DBE2C64F445008EBCAA /* Printer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7B13DBC2C64F445008EBCAA /* Printer.swift */; };
D7B2B6EA245EEA620084B78D /* LanguageType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7A65C5820F11C38003E5ADC /* LanguageType.swift */; };
D7B2B6EC245EEA790084B78D /* LanguageType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7A65C5820F11C38003E5ADC /* LanguageType.swift */; };
D7B34F9725195D7E0007877E /* PreviewState.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7B34F9625195D7E0007877E /* PreviewState.swift */; };
D7B34F9825195D7E0007877E /* PreviewState.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7B34F9625195D7E0007877E /* PreviewState.swift */; };
D7B34F9A25195D7E0007877E /* PreviewState.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7B34F9625195D7E0007877E /* PreviewState.swift */; };
D7B34F9B25195D7E0007877E /* PreviewState.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7B34F9625195D7E0007877E /* PreviewState.swift */; };
D7B3FE7021027A5E00764C39 /* UserDataService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F13BB3820FEDE230005E120 /* UserDataService.swift */; };
D7B3FE7121027A6D00764C39 /* UserDataService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F13BB3820FEDE230005E120 /* UserDataService.swift */; };
D7B4AC5E2471253100F3888A /* NoteMeta.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7B4AC5D2471253100F3888A /* NoteMeta.swift */; };
D7B4AC5F2471253100F3888A /* NoteMeta.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7B4AC5D2471253100F3888A /* NoteMeta.swift */; };
D7B4AC612471253100F3888A /* NoteMeta.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7B4AC5D2471253100F3888A /* NoteMeta.swift */; };
D7B4AC622471253100F3888A /* NoteMeta.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7B4AC5D2471253100F3888A /* NoteMeta.swift */; };
D7B6E59A207912E300FE0E20 /* Project.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7B6E599207912E300FE0E20 /* Project.swift */; };
D7B6E59B207912E300FE0E20 /* Project.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7B6E599207912E300FE0E20 /* Project.swift */; };
D7B6E59D20794B8C00FE0E20 /* Project.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7B6E599207912E300FE0E20 /* Project.swift */; };
D7BA204D2186E3DD0064824B /* TitleBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2799407B218484C900727B20 /* TitleBarView.swift */; };
D7BAC62F249D11F8008D29AA /* SettingsFilesNaming.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7BAC62E249D11F8008D29AA /* SettingsFilesNaming.swift */; };
D7BAC631249D1204008D29AA /* SettingsFilesNaming.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7BAC62E249D11F8008D29AA /* SettingsFilesNaming.swift */; };
D7BB2DFE29A0157700D5055A /* Storage+Git.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7BB2DFD29A0157700D5055A /* Storage+Git.swift */; };
D7BB2DFF29A0157700D5055A /* Storage+Git.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7BB2DFD29A0157700D5055A /* Storage+Git.swift */; };
D7BB2E0129A0157700D5055A /* Storage+Git.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7BB2DFD29A0157700D5055A /* Storage+Git.swift */; };
D7BCF035296B0DAA00F72A4F /* AboutImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7BCF034296B0DAA00F72A4F /* AboutImageView.swift */; };
D7BCF036296B0DAA00F72A4F /* AboutImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7BCF034296B0DAA00F72A4F /* AboutImageView.swift */; };
D7BDFE59201F671900897A58 /* Storage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7E025071F3B6DDB00EDDA32 /* Storage.swift */; };
D7BDFE5D201F677B00897A58 /* UserDefaultsManagement.swift in Sources */ = {isa = PBXBuildFile; fileRef = D76447DB1F3A4F0700965F01 /* UserDefaultsManagement.swift */; };
D7BDFE60201F677B00897A58 /* NoteType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D708AC662000EF5800A1760F /* NoteType.swift */; };
D7BDFE61201F677B00897A58 /* SortBy.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7679375201F0BFD000F7BBF /* SortBy.swift */; };
D7BDFE62201F678C00897A58 /* Note.swift in Sources */ = {isa = PBXBuildFile; fileRef = D79FE8A01F77D04A00113CFD /* Note.swift */; };
D7BDFE68201F67DA00897A58 /* NotesTextProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7F95F391FF2759300E2A447 /* NotesTextProcessor.swift */; };
D7BDFE6A201F68B700897A58 /* NotesTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7BDFE69201F68B700897A58 /* NotesTableView.swift */; };
D7BDFE6C201F6DC200897A58 /* EditTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7BDFE6B201F6DC200897A58 /* EditTextView.swift */; };
D7BDFE70201F788D00897A58 /* NoteCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7BDFE6F201F788D00897A58 /* NoteCellView.swift */; };
D7C1C99A235606CB0021A32D /* SidebarHeaderCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7C1C999235606CB0021A32D /* SidebarHeaderCellView.swift */; };
D7C1C99B235606CB0021A32D /* SidebarHeaderCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7C1C999235606CB0021A32D /* SidebarHeaderCellView.swift */; };
D7C33F6E29E09A690006C473 /* AppIconViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7C33F6D29E09A690006C473 /* AppIconViewController.swift */; };
D7C6DB5B25AA880600F8F76F /* ViewController+More.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7C6DB5A25AA880600F8F76F /* ViewController+More.swift */; };
D7C803EE2046DBBD005DA599 /* DefaultExtensionControllerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7C803ED2046DBBD005DA599 /* DefaultExtensionControllerView.swift */; };
D7C9029223547A1E00A89BD8 /* FSTag.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7C9029123547A1E00A89BD8 /* FSTag.swift */; };
D7C9029323547A1E00A89BD8 /* FSTag.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7C9029123547A1E00A89BD8 /* FSTag.swift */; };
D7C9029523547A1E00A89BD8 /* FSTag.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7C9029123547A1E00A89BD8 /* FSTag.swift */; };
D7CA7FD4232652E300E9717A /* PreferencesGitViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7CA7FD3232652E300E9717A /* PreferencesGitViewController.swift */; };
D7CA7FD5232652E300E9717A /* PreferencesGitViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7CA7FD3232652E300E9717A /* PreferencesGitViewController.swift */; };
D7CB9905207E5AE300037E91 /* SidebarTableRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7CB9904207E5AE300037E91 /* SidebarTableRowView.swift */; };
D7CB9906207E5AE300037E91 /* SidebarTableRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7CB9904207E5AE300037E91 /* SidebarTableRowView.swift */; };
D7CBAFFE214D5A1C002ECD5A /* ShortcutIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7CBAFFD214D5A1C002ECD5A /* ShortcutIdentifier.swift */; };
D7CC44C12A1E5E4F00743857 /* ViewController+WebApi.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7CC44C02A1E5E4F00743857 /* ViewController+WebApi.swift */; };
D7CC44C22A1E5E4F00743857 /* ViewController+WebApi.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7CC44C02A1E5E4F00743857 /* ViewController+WebApi.swift */; };
D7CC44C42A1E5E4F00743857 /* ViewController+WebApi.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7CC44C02A1E5E4F00743857 /* ViewController+WebApi.swift */; };
D7CC44C62A1E5F7600743857 /* ApiResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7CC44C52A1E5F7600743857 /* ApiResponse.swift */; };
D7CC44C72A1E5F7600743857 /* ApiResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7CC44C52A1E5F7600743857 /* ApiResponse.swift */; };
D7CC44C92A1E5F7600743857 /* ApiResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7CC44C52A1E5F7600743857 /* ApiResponse.swift */; };
D7CCEDB92C6BA2F300A3BB83 /* ClickableTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7CCEDB82C6BA2F300A3BB83 /* ClickableTextField.swift */; };
D7CCEDBA2C6BA2F300A3BB83 /* ClickableTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7CCEDB82C6BA2F300A3BB83 /* ClickableTextField.swift */; };
D7CD5CC42181F7530009D63B /* Storage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7E025071F3B6DDB00EDDA32 /* Storage.swift */; };
D7CD5CC5218209820009D63B /* UserDefaultsManagement.swift in Sources */ = {isa = PBXBuildFile; fileRef = D76447DB1F3A4F0700965F01 /* UserDefaultsManagement.swift */; };
D7CD5CC6218209960009D63B /* Project.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7B6E599207912E300FE0E20 /* Project.swift */; };
D7CD5CC7218209BD0009D63B /* SortBy.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7679375201F0BFD000F7BBF /* SortBy.swift */; };
D7CD5CC9218209D80009D63B /* NoteType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D708AC662000EF5800A1760F /* NoteType.swift */; };
D7CD5CCC21820B7A0009D63B /* UserDefaultsManagement+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7CD5CCA21820A380009D63B /* UserDefaultsManagement+.swift */; };
D7CD5CCD21820B7B0009D63B /* UserDefaultsManagement+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7CD5CCA21820A380009D63B /* UserDefaultsManagement+.swift */; };
D7CD5CCE21820C9D0009D63B /* DateFormatter+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F13BB2820FEDE230005E120 /* DateFormatter+.swift */; };
D7CD5CD021820CBC0009D63B /* URL+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F13BB2A20FEDE230005E120 /* URL+.swift */; };
D7CD5CD121820CCD0009D63B /* Date+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D76E10C0215A55CE0017F4A3 /* Date+.swift */; };
D7CD5CD421820D640009D63B /* NSAttributedStringKey+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7487FE82174E5CB00D09383 /* NSAttributedStringKey+.swift */; };
D7CD5CD521820D700009D63B /* ImagesProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D777D7802009115C00D86B33 /* ImagesProcessor.swift */; };
D7CD5CDB21832C190009D63B /* UserDefaultsManagement+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7CD5CDA21832C190009D63B /* UserDefaultsManagement+.swift */; };
D7CD5CDC21832C190009D63B /* UserDefaultsManagement+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7CD5CDA21832C190009D63B /* UserDefaultsManagement+.swift */; };
D7CD5F681F508E74006AA35D /* SourceCodePro-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7CD5F671F508E6A006AA35D /* SourceCodePro-Bold.ttf */; };
D7CD5F691F508E74006AA35D /* SourceCodePro-BoldIt.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7CD5F661F508E6A006AA35D /* SourceCodePro-BoldIt.ttf */; };
D7CD5F6C1F51185F006AA35D /* NSFont+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7CD5F6B1F51185F006AA35D /* NSFont+.swift */; };
D7CDE9DC2161767A00DC5978 /* AppearanceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7CDE9DB2161767A00DC5978 /* AppearanceType.swift */; };
D7CDE9DD2161767B00DC5978 /* AppearanceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7CDE9DB2161767A00DC5978 /* AppearanceType.swift */; };
D7CDE9DE216178DE00DC5978 /* AppearanceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7CDE9DB2161767A00DC5978 /* AppearanceType.swift */; };
D7CE196C1FA4BA5E004BF8EE /* PreviewTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7CE196B1FA4BA5E004BF8EE /* PreviewTextField.swift */; };
D7CF7EAB29E2093C00FEC0C5 /* SecurityViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7CF7EAA29E2093C00FEC0C5 /* SecurityViewController.swift */; };
D7D01AFD2C65203A00F545D0 /* PrinterLegacy.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7D01AFC2C65203A00F545D0 /* PrinterLegacy.swift */; };
D7D01AFE2C65208000F545D0 /* PrinterLegacy.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7D01AFC2C65203A00F545D0 /* PrinterLegacy.swift */; };
D7D03BAF205C250500D96A6D /* FontViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7D03BAE205C250500D96A6D /* FontViewController.swift */; };
D7D1DE68216D05A800AC1845 /* NameTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7D1DE67216D05A800AC1845 /* NameTextField.swift */; };
D7D1DE69216D05A800AC1845 /* NameTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7D1DE67216D05A800AC1845 /* NameTextField.swift */; };
D7D2F27E2B54BD42003DCA47 /* Shout in Frameworks */ = {isa = PBXBuildFile; productRef = D7D2F27D2B54BD42003DCA47 /* Shout */; };
D7D2F2802B54BDD4003DCA47 /* Shout in Frameworks */ = {isa = PBXBuildFile; productRef = D7D2F27F2B54BDD4003DCA47 /* Shout */; };
D7D2F2822B54BE59003DCA47 /* Shout in Frameworks */ = {isa = PBXBuildFile; productRef = D7D2F2812B54BE59003DCA47 /* Shout */; };
D7D372F4207B5B0F00AFBD9F /* SidebarNotesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7D372F3207B5B0F00AFBD9F /* SidebarNotesView.swift */; };
D7D372F5207B5B0F00AFBD9F /* SidebarNotesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7D372F3207B5B0F00AFBD9F /* SidebarNotesView.swift */; };
D7D372F7207BB09500AFBD9F /* SidebarOutlineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7D372F6207BB09500AFBD9F /* SidebarOutlineView.swift */; };
D7D372F8207BB09500AFBD9F /* SidebarOutlineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7D372F6207BB09500AFBD9F /* SidebarOutlineView.swift */; };
D7D3D2A427BEEA61001C1497 /* Note+History.swift in Sources */ = {isa = PBXBuildFile; fileRef = D736DDAC27BAC7940012ED70 /* Note+History.swift */; };
D7D3D2A527BEEA62001C1497 /* Note+History.swift in Sources */ = {isa = PBXBuildFile; fileRef = D736DDAC27BAC7940012ED70 /* Note+History.swift */; };
D7D79C28236798C300898A2D /* Welcome.bundle in Resources */ = {isa = PBXBuildFile; fileRef = D7D79C27236798C300898A2D /* Welcome.bundle */; };
D7D79C29236798C300898A2D /* Welcome.bundle in Resources */ = {isa = PBXBuildFile; fileRef = D7D79C27236798C300898A2D /* Welcome.bundle */; };
D7D7CD3A232774BC0016AC15 /* ViewController+Git.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7D7CD39232774BC0016AC15 /* ViewController+Git.swift */; };
D7D7CD3B232774BC0016AC15 /* ViewController+Git.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7D7CD39232774BC0016AC15 /* ViewController+Git.swift */; };
D7D9503D209D806F001FB60B /* SidebarTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7D9503C209D806F001FB60B /* SidebarTableView.swift */; };
D7D9503F209D846E001FB60B /* SidebarTableCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7D9503E209D846E001FB60B /* SidebarTableCellView.swift */; };
D7D97F3C290437A200C651D4 /* NSWindowController+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7D97F3B290437A200C651D4 /* NSWindowController+.swift */; };
D7D97F3D290437A200C651D4 /* NSWindowController+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7D97F3B290437A200C651D4 /* NSWindowController+.swift */; };
D7DA9E1E21031901001CF0BE /* OutlineHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7DA9E1D21031901001CF0BE /* OutlineHeaderView.swift */; };
D7DA9E1F21031901001CF0BE /* OutlineHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7DA9E1D21031901001CF0BE /* OutlineHeaderView.swift */; };
D7DA9E2121033489001CF0BE /* NSMutableAttributedString+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7DA9E2021033489001CF0BE /* NSMutableAttributedString+.swift */; };
D7DA9E2221033489001CF0BE /* NSMutableAttributedString+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7DA9E2021033489001CF0BE /* NSMutableAttributedString+.swift */; };
D7DA9E2321033834001CF0BE /* NSMutableAttributedString+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7DA9E2021033489001CF0BE /* NSMutableAttributedString+.swift */; };
D7DD5A881F88D4EA00CE947E /* FileWatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7DD5A871F88D4EA00CE947E /* FileWatcher.swift */; };
D7DD5A8A1F88D50000CE947E /* FileWatcherEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7DD5A891F88D50000CE947E /* FileWatcherEvent.swift */; };
D7DD79581F4E60D000D5724B /* SourceCodePro-Black.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7DD79561F4E606600D5724B /* SourceCodePro-Black.ttf */; };
D7DD79591F4E60D000D5724B /* SourceCodePro-It.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7DD79551F4E606600D5724B /* SourceCodePro-It.ttf */; };
D7DD795B1F4E611D00D5724B /* SourceCodePro-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7DD795A1F4E611200D5724B /* SourceCodePro-Regular.ttf */; };
D7E025081F3B6DDB00EDDA32 /* Storage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7E025071F3B6DDB00EDDA32 /* Storage.swift */; };
D7E32C2C28F8D0740048614B /* StaticSshKeyDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7E32C2B28F8D0740048614B /* StaticSshKeyDelegate.swift */; };
D7E32C2D28F8D0750048614B /* StaticSshKeyDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7E32C2B28F8D0740048614B /* StaticSshKeyDelegate.swift */; };
D7E51713220D814D00A9CAD9 /* UTI.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7E51712220D814D00A9CAD9 /* UTI.swift */; };
D7E51714220D814D00A9CAD9 /* UTI.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7E51712220D814D00A9CAD9 /* UTI.swift */; };
D7E6ACE920832D41003599A2 /* AppDelegate+URLRoutes.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7E6ACE820832D40003599A2 /* AppDelegate+URLRoutes.swift */; };
D7E6ACEA20832D41003599A2 /* AppDelegate+URLRoutes.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7E6ACE820832D40003599A2 /* AppDelegate+URLRoutes.swift */; };
D7E6D9D320808623003ECAFC /* SidebarItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D75EE7F62078B22D0055F159 /* SidebarItem.swift */; };
D7E6D9D42080862F003ECAFC /* SidebarItemType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D75EE7FF2078E0C60055F159 /* SidebarItemType.swift */; };
D7E7DB3327A9B17000408725 /* DatePickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7E7DB3227A9B16F00408725 /* DatePickerViewController.swift */; };
D7E81C2E1F925B5F00416A91 /* PrefsWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D779C7BA1F415BE300FADEE1 /* PrefsWindowController.swift */; };
D7E81C2F1F925B5F00416A91 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7793C741F211C6000CA39B7 /* ViewController.swift */; };
D7E81C301F925B5F00416A91 /* FileWatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7DD5A871F88D4EA00CE947E /* FileWatcher.swift */; };
D7E81C321F925B5F00416A91 /* PrefsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7508FCD1F3438540047AB76 /* PrefsViewController.swift */; };
D7E81C331F925B5F00416A91 /* UserDefaultsManagement.swift in Sources */ = {isa = PBXBuildFile; fileRef = D76447DB1F3A4F0700965F01 /* UserDefaultsManagement.swift */; };
D7E81C341F925B5F00416A91 /* EditTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D797004B1F3DD10700BAD94D /* EditTextView.swift */; };
D7E81C361F925B5F00416A91 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7793C721F211C6000CA39B7 /* AppDelegate.swift */; };
D7E81C371F925B5F00416A91 /* NoteRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D735E5BE1F2F001500173215 /* NoteRowView.swift */; };
D7E81C381F925B5F00416A91 /* Storage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7E025071F3B6DDB00EDDA32 /* Storage.swift */; };
D7E81C391F925B5F00416A91 /* FileWatcherEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7DD5A891F88D50000CE947E /* FileWatcherEvent.swift */; };
D7E81C3A1F925B5F00416A91 /* NotesTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7A415131F2FBDA00099B82C /* NotesTableView.swift */; };
D7E81C3D1F925B5F00416A91 /* SandboxBookmark.swift in Sources */ = {isa = PBXBuildFile; fileRef = D773DE7F1F36F45900A39C9F /* SandboxBookmark.swift */; };
D7E81C3F1F925B5F00416A91 /* NSFont+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7CD5F6B1F51185F006AA35D /* NSFont+.swift */; };
D7E81C411F925B5F00416A91 /* SearchTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7508FC71F337E850047AB76 /* SearchTextField.swift */; };
D7E81C421F925B5F00416A91 /* MainWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 275592961F3AE9B5006B8988 /* MainWindowController.swift */; };
D7E81C441F925B5F00416A91 /* NoteCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D735E5BC1F2EF66000173215 /* NoteCellView.swift */; };
D7E81C461F925B5F00416A91 /* Note.swift in Sources */ = {isa = PBXBuildFile; fileRef = D79FE8A01F77D04A00113CFD /* Note.swift */; };
D7E81C4B1F925B5F00416A91 /* MPreview.bundle in Resources */ = {isa = PBXBuildFile; fileRef = D71C4A4D1F520F0E00EBA30B /* MPreview.bundle */; };
D7E81C4C1F925B5F00416A91 /* SourceCodePro-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7CD5F671F508E6A006AA35D /* SourceCodePro-Bold.ttf */; };
D7E81C4D1F925B5F00416A91 /* SourceCodePro-BoldIt.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7CD5F661F508E6A006AA35D /* SourceCodePro-BoldIt.ttf */; };
D7E81C4E1F925B5F00416A91 /* SourceCodePro-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7DD795A1F4E611200D5724B /* SourceCodePro-Regular.ttf */; };
D7E81C4F1F925B5F00416A91 /* SourceCodePro-Black.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7DD79561F4E606600D5724B /* SourceCodePro-Black.ttf */; };
D7E81C501F925B5F00416A91 /* SourceCodePro-It.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7DD79551F4E606600D5724B /* SourceCodePro-It.ttf */; };
D7E81C531F925B5F00416A91 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D7793C781F211C6000CA39B7 /* Main.storyboard */; };
D7E9FEBA2C4AA59D0025D8E3 /* SidebarItemType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D75EE7FF2078E0C60055F159 /* SidebarItemType.swift */; };
D7E9FEBC2C4AA64B0025D8E3 /* SearchQuery.swift in Sources */ = {isa = PBXBuildFile; fileRef = D714749C279D7DBC001A8B29 /* SearchQuery.swift */; };
D7ECE68A22B6B481006A14C6 /* TextBundle.icns in Resources */ = {isa = PBXBuildFile; fileRef = D720240B22A9412B000A7691 /* TextBundle.icns */; };
D7EDEDFB219203C9000B8C1A /* NoteCellView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7EDEDFA219203C9000B8C1A /* NoteCellView+.swift */; };
D7EDEDFC219203C9000B8C1A /* NoteCellView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7EDEDFA219203C9000B8C1A /* NoteCellView+.swift */; };
D7EDEDFD21920402000B8C1A /* NoteCellView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7EDEDFA219203C9000B8C1A /* NoteCellView+.swift */; };
D7F2F19721C503F000E41811 /* AvenirNext-MediumItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F18721C503EF00E41811 /* AvenirNext-MediumItalic.ttf */; };
D7F2F19821C503F000E41811 /* AvenirNext-MediumItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F18721C503EF00E41811 /* AvenirNext-MediumItalic.ttf */; };
D7F2F19921C503F000E41811 /* AvenirNext-MediumItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F18721C503EF00E41811 /* AvenirNext-MediumItalic.ttf */; };
D7F2F19A21C503F000E41811 /* AvenirNext-UltraLight.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F18821C503EF00E41811 /* AvenirNext-UltraLight.ttf */; };
D7F2F19B21C503F000E41811 /* AvenirNext-UltraLight.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F18821C503EF00E41811 /* AvenirNext-UltraLight.ttf */; };
D7F2F19C21C503F000E41811 /* AvenirNext-UltraLight.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F18821C503EF00E41811 /* AvenirNext-UltraLight.ttf */; };
D7F2F19D21C503F000E41811 /* AvenirNext-Medium.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F18921C503EF00E41811 /* AvenirNext-Medium.ttf */; };
D7F2F19E21C503F000E41811 /* AvenirNext-Medium.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F18921C503EF00E41811 /* AvenirNext-Medium.ttf */; };
D7F2F19F21C503F000E41811 /* AvenirNext-Medium.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F18921C503EF00E41811 /* AvenirNext-Medium.ttf */; };
D7F2F1A021C503F000E41811 /* AvenirNext-Heavy.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F18A21C503EF00E41811 /* AvenirNext-Heavy.ttf */; };
D7F2F1A121C503F000E41811 /* AvenirNext-Heavy.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F18A21C503EF00E41811 /* AvenirNext-Heavy.ttf */; };
D7F2F1A221C503F000E41811 /* AvenirNext-Heavy.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F18A21C503EF00E41811 /* AvenirNext-Heavy.ttf */; };
D7F2F1A321C503F000E41811 /* AvenirNext-DemiItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F18B21C503EF00E41811 /* AvenirNext-DemiItalic.ttf */; };
D7F2F1A421C503F000E41811 /* AvenirNext-DemiItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F18B21C503EF00E41811 /* AvenirNext-DemiItalic.ttf */; };
D7F2F1A521C503F000E41811 /* AvenirNext-DemiItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F18B21C503EF00E41811 /* AvenirNext-DemiItalic.ttf */; };
D7F2F1A621C503F000E41811 /* AvenirNext-BoldItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F18C21C503EF00E41811 /* AvenirNext-BoldItalic.ttf */; };
D7F2F1A721C503F000E41811 /* AvenirNext-BoldItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F18C21C503EF00E41811 /* AvenirNext-BoldItalic.ttf */; };
D7F2F1A821C503F000E41811 /* AvenirNext-BoldItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F18C21C503EF00E41811 /* AvenirNext-BoldItalic.ttf */; };
D7F2F1A921C503F000E41811 /* AvenirNext-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F18D21C503EF00E41811 /* AvenirNext-Regular.ttf */; };
D7F2F1AA21C503F000E41811 /* AvenirNext-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F18D21C503EF00E41811 /* AvenirNext-Regular.ttf */; };
D7F2F1AB21C503F000E41811 /* AvenirNext-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F18D21C503EF00E41811 /* AvenirNext-Regular.ttf */; };
D7F2F1AC21C503F000E41811 /* AvenirNext-Light.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F18E21C503EF00E41811 /* AvenirNext-Light.ttf */; };
D7F2F1AD21C503F000E41811 /* AvenirNext-Light.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F18E21C503EF00E41811 /* AvenirNext-Light.ttf */; };
D7F2F1AE21C503F000E41811 /* AvenirNext-Light.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F18E21C503EF00E41811 /* AvenirNext-Light.ttf */; };
D7F2F1AF21C503F000E41811 /* AvenirNext-Demi.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F18F21C503EF00E41811 /* AvenirNext-Demi.ttf */; };
D7F2F1B021C503F000E41811 /* AvenirNext-Demi.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F18F21C503EF00E41811 /* AvenirNext-Demi.ttf */; };
D7F2F1B121C503F000E41811 /* AvenirNext-Demi.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F18F21C503EF00E41811 /* AvenirNext-Demi.ttf */; };
D7F2F1B221C503F000E41811 /* AvenirNext-HeavyItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F19021C503EF00E41811 /* AvenirNext-HeavyItalic.ttf */; };
D7F2F1B321C503F000E41811 /* AvenirNext-HeavyItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F19021C503EF00E41811 /* AvenirNext-HeavyItalic.ttf */; };
D7F2F1B421C503F000E41811 /* AvenirNext-HeavyItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F19021C503EF00E41811 /* AvenirNext-HeavyItalic.ttf */; };
D7F2F1B521C503F000E41811 /* AvenirNext-ThinItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F19121C503F000E41811 /* AvenirNext-ThinItalic.ttf */; };
D7F2F1B621C503F000E41811 /* AvenirNext-ThinItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F19121C503F000E41811 /* AvenirNext-ThinItalic.ttf */; };
D7F2F1B721C503F000E41811 /* AvenirNext-ThinItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F19121C503F000E41811 /* AvenirNext-ThinItalic.ttf */; };
D7F2F1B821C503F000E41811 /* AvenirNext-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F19221C503F000E41811 /* AvenirNext-Bold.ttf */; };
D7F2F1B921C503F000E41811 /* AvenirNext-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F19221C503F000E41811 /* AvenirNext-Bold.ttf */; };
D7F2F1BA21C503F000E41811 /* AvenirNext-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F19221C503F000E41811 /* AvenirNext-Bold.ttf */; };
D7F2F1BB21C503F000E41811 /* AvenirNext-Thin.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F19321C503F000E41811 /* AvenirNext-Thin.ttf */; };
D7F2F1BC21C503F000E41811 /* AvenirNext-Thin.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F19321C503F000E41811 /* AvenirNext-Thin.ttf */; };
D7F2F1BD21C503F000E41811 /* AvenirNext-Thin.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F19321C503F000E41811 /* AvenirNext-Thin.ttf */; };
D7F2F1BE21C503F000E41811 /* AvenirNext-Italic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F19421C503F000E41811 /* AvenirNext-Italic.ttf */; };
D7F2F1BF21C503F000E41811 /* AvenirNext-Italic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F19421C503F000E41811 /* AvenirNext-Italic.ttf */; };
D7F2F1C021C503F000E41811 /* AvenirNext-Italic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F19421C503F000E41811 /* AvenirNext-Italic.ttf */; };
D7F2F1C121C503F000E41811 /* AvenirNext-LightItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F19521C503F000E41811 /* AvenirNext-LightItalic.ttf */; };
D7F2F1C221C503F000E41811 /* AvenirNext-LightItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F19521C503F000E41811 /* AvenirNext-LightItalic.ttf */; };
D7F2F1C321C503F000E41811 /* AvenirNext-LightItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F19521C503F000E41811 /* AvenirNext-LightItalic.ttf */; };
D7F2F1C421C503F000E41811 /* AvenirNext-UltraLightIt.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F19621C503F000E41811 /* AvenirNext-UltraLightIt.ttf */; };
D7F2F1C521C503F000E41811 /* AvenirNext-UltraLightIt.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F19621C503F000E41811 /* AvenirNext-UltraLightIt.ttf */; };
D7F2F1C621C503F000E41811 /* AvenirNext-UltraLightIt.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7F2F19621C503F000E41811 /* AvenirNext-UltraLightIt.ttf */; };
D7F5C0EF223ED0570038F172 /* PreferencesGeneralViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7F5C0EE223ED0570038F172 /* PreferencesGeneralViewController.swift */; };
D7F5C0F0223ED0570038F172 /* PreferencesGeneralViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7F5C0EE223ED0570038F172 /* PreferencesGeneralViewController.swift */; };
D7F5C0F2223ED0C00038F172 /* PreferencesUserInterfaceViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7F5C0F1223ED0C00038F172 /* PreferencesUserInterfaceViewController.swift */; };
D7F5C0F3223ED0C00038F172 /* PreferencesUserInterfaceViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7F5C0F1223ED0C00038F172 /* PreferencesUserInterfaceViewController.swift */; };
D7F5C0F5223ED5620038F172 /* PreferencesEditorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7F5C0F4223ED5620038F172 /* PreferencesEditorViewController.swift */; };
D7F5C0F6223ED5620038F172 /* PreferencesEditorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7F5C0F4223ED5620038F172 /* PreferencesEditorViewController.swift */; };
D7F5C0F8223ED57D0038F172 /* PreferencesSecurityViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7F5C0F7223ED57D0038F172 /* PreferencesSecurityViewController.swift */; };
D7F5C0F9223ED57D0038F172 /* PreferencesSecurityViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7F5C0F7223ED57D0038F172 /* PreferencesSecurityViewController.swift */; };
D7F5C0FB223ED58F0038F172 /* PreferencesAdvancedViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7F5C0FA223ED58F0038F172 /* PreferencesAdvancedViewController.swift */; };
D7F5C0FC223ED58F0038F172 /* PreferencesAdvancedViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7F5C0FA223ED58F0038F172 /* PreferencesAdvancedViewController.swift */; };
D7F6CFF02056AC22008C584A /* LanguageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7F6CFEF2056AC22008C584A /* LanguageViewController.swift */; };
D7F95F3A1FF2759300E2A447 /* NotesTextProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7F95F391FF2759300E2A447 /* NotesTextProcessor.swift */; };
D7FA916520555067002BB0AB /* SourceCodePro-Black.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7DD79561F4E606600D5724B /* SourceCodePro-Black.ttf */; };
D7FA916620555067002BB0AB /* SourceCodePro-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7CD5F671F508E6A006AA35D /* SourceCodePro-Bold.ttf */; };
D7FA916720555067002BB0AB /* SourceCodePro-BoldIt.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7CD5F661F508E6A006AA35D /* SourceCodePro-BoldIt.ttf */; };
D7FA916820555067002BB0AB /* SourceCodePro-It.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7DD79551F4E606600D5724B /* SourceCodePro-It.ttf */; };
D7FA916920555067002BB0AB /* SourceCodePro-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7DD795A1F4E611200D5724B /* SourceCodePro-Regular.ttf */; };
D7FB716C2BE7F66500808E56 /* EditorViewController+QuickLook.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7FB716B2BE7F66500808E56 /* EditorViewController+QuickLook.swift */; };
D7FDA4F7236DBC6900C3B4AA /* Sidebar.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7FDA4F6236DBC6900C3B4AA /* Sidebar.swift */; };
D7FFD09C1FF677ED0064CBA6 /* NotesTextProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7F95F391FF2759300E2A447 /* NotesTextProcessor.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
D75F333E205EC34800CC887E /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = D7793C671F211C6000CA39B7 /* Project object */;
proxyType = 1;
remoteGlobalIDString = D75F3335205EC34800CC887E;
remoteInfo = "FSNotes iOS Share";
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
6F13BB1A20FEDDF50005E120 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
6F13BB6620FEDE560005E120 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
D713542C2042D46E00E3776F /* Embed Watch Content */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "$(CONTENTS_FOLDER_PATH)/Watch";
dstSubfolderSpec = 16;
files = (
);
name = "Embed Watch Content";
runOnlyForDeploymentPostprocessing = 0;
};
D721893F21020D3300FE3AF2 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
D73E3DE0205D17360044FF84 /* Embed App Extensions */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 13;
files = (
D75F3340205EC34800CC887E /* FSNotes iOS Share Extension.appex in Embed App Extensions */,
);
name = "Embed App Extensions";
runOnlyForDeploymentPostprocessing = 0;
};
D7D7CD56232791670016AC15 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 6;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
D7D7CD58232791810016AC15 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 7;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
1102DDB02EE4C277005029A6 /* EditTextView+Complete.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "EditTextView+Complete.swift"; sourceTree = ""; };
110BE0102EE86B4600C5E456 /* Clojure.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Clojure.swift; sourceTree = ""; };
110BE0142EE8C1C600C5E456 /* Html.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Html.swift; sourceTree = ""; };
110BE0182EE8C24B00C5E456 /* Css.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Css.swift; sourceTree = ""; };
110BE01C2EE8C3BA00C5E456 /* Shell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Shell.swift; sourceTree = ""; };
110BE0202EE8C53600C5E456 /* TypeScript.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TypeScript.swift; sourceTree = ""; };
110BE0242EE8C5AC00C5E456 /* Lisp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Lisp.swift; sourceTree = ""; };
110D09812E9C1525001555FA /* NSRange+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSRange+.swift"; sourceTree = ""; };
110E409D2EA0150000C62F49 /* NSTextCheckingResult+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSTextCheckingResult+.swift"; sourceTree = ""; };
110E40A32EA039AA00C62F49 /* EditTextView+DragOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "EditTextView+DragOperation.swift"; sourceTree = ""; };
111013142EC8F1B600B6CF1B /* ImagePreviewViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImagePreviewViewController.swift; sourceTree = ""; };
113685592EC7A2130033767F /* NSMutableAttributedString+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSMutableAttributedString+.swift"; sourceTree = ""; };
1136855B2EC7A69C0033767F /* Platform.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Platform.swift; sourceTree = ""; };
113685612EC869860033767F /* URL+Image.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URL+Image.swift"; sourceTree = ""; };
113685672EC889DC0033767F /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; };
113685692EC8AE260033767F /* UIBarButtonItem+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIBarButtonItem+.swift"; sourceTree = ""; };
113A319F2EEE2D3A009B50B0 /* Note+Preview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Note+Preview.swift"; sourceTree = ""; };
11598DA22EDCB8D40036E387 /* UIFont+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIFont+.swift"; sourceTree = ""; };
116182862E62B046005B5EE0 /* SwiftHighlighter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftHighlighter.swift; sourceTree = ""; };
1166D1F62E91BA7F00B061CA /* CodeBlockDetector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CodeBlockDetector.swift; sourceTree = ""; };
1175E0912EDC929400B92794 /* ny-2026.icon */ = {isa = PBXFileReference; lastKnownFileType = folder.iconcomposer.icon; path = "ny-2026.icon"; sourceTree = ""; };
1175E0992EDCA60200B92794 /* FSNotes - Readme.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = "FSNotes - Readme.md"; sourceTree = ""; };
1175E09A2EDCA60200B92794 /* FSNotes 4.0 Change Log.textbundle */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = "FSNotes 4.0 Change Log.textbundle"; sourceTree = ""; };
1175E09B2EDCA60200B92794 /* FSNotes 4.0 for iOS.textbundle */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = "FSNotes 4.0 for iOS.textbundle"; sourceTree = ""; };
1175E09C2EDCA60200B92794 /* FSNotes 5.0 Change Log.textbundle */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = "FSNotes 5.0 Change Log.textbundle"; sourceTree = ""; };
1175E09D2EDCA60200B92794 /* Meet FSNotes 6.textbundle */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = "Meet FSNotes 6.textbundle"; sourceTree = ""; };
117C0E4C2EEDB9B70086419C /* EditTextView+Clicked.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "EditTextView+Clicked.swift"; sourceTree = ""; };
11A6A8F92EF06B90005D000A /* EditTextView+MoveLines.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "EditTextView+MoveLines.swift"; sourceTree = ""; };
11A6A8FC2EF074D2005D000A /* EditTextView+Todo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "EditTextView+Todo.swift"; sourceTree = ""; };
11A95B612EDC56DC0081ED29 /* modern.icon */ = {isa = PBXFileReference; lastKnownFileType = folder.iconcomposer.icon; path = modern.icon; sourceTree = ""; };
11AA4B1E2EF9A4680075A9E4 /* EditorViewController+ScrollPosition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "EditorViewController+ScrollPosition.swift"; sourceTree = ""; };
11ABE5E12EEEFCF700E7C9EB /* NotesCounterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotesCounterView.swift; sourceTree = ""; };
11AF633D2E898430004E7157 /* Sql.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sql.swift; sourceTree = ""; };
11B3F5952F182E4E00A3531D /* EditorViewController+Search.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "EditorViewController+Search.swift"; sourceTree = ""; };
11BD71652EDC87B700541BF9 /* classic-2025.icon */ = {isa = PBXFileReference; lastKnownFileType = folder.iconcomposer.icon; path = "classic-2025.icon"; sourceTree = ""; };
11BD8F912EDDEC33000673A7 /* GitHubDark.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GitHubDark.swift; sourceTree = ""; };
11BD8F952EDDF320000673A7 /* SolarizedLight.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SolarizedLight.swift; sourceTree = ""; };
11BD8F992EDDF332000673A7 /* SolarizedDark.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SolarizedDark.swift; sourceTree = ""; };
11BD8F9D2EDE022C000673A7 /* AtomOneLight.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AtomOneLight.swift; sourceTree = ""; };
11BD8FA12EDE023E000673A7 /* AtomOneDark.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AtomOneDark.swift; sourceTree = ""; };
11BD8FA52EDE0679000673A7 /* Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Theme.swift; sourceTree = ""; };
11BF06692EE331B2006C7336 /* Scala.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Scala.swift; sourceTree = ""; };
11BF066D2EE331FE006C7336 /* Bash.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bash.swift; sourceTree = ""; };
11BF06712EE3325F006C7336 /* Haskell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Haskell.swift; sourceTree = ""; };
11BF06752EE49542006C7336 /* Lua.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Lua.swift; sourceTree = ""; };
11BF06792EE495C0006C7336 /* Perl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Perl.swift; sourceTree = ""; };
11BF067D2EE49689006C7336 /* Erlang.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Erlang.swift; sourceTree = ""; };
11D6C0C62EE22567006017F0 /* Python.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Python.swift; sourceTree = ""; };
11D6C0CA2EE225E1006017F0 /* C.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = C.swift; sourceTree = ""; };
11D6C0CE2EE22799006017F0 /* Cpp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Cpp.swift; sourceTree = ""; };
11D6C0D22EE227F6006017F0 /* Java.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Java.swift; sourceTree = ""; };
11D6C0D62EE229E7006017F0 /* Go.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Go.swift; sourceTree = ""; };
11D6C0DA2EE22B0D006017F0 /* Rust.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Rust.swift; sourceTree = ""; };
11D6C0DE2EE22B74006017F0 /* Csharp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Csharp.swift; sourceTree = ""; };
11D6C0E22EE22BEE006017F0 /* Kotlin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Kotlin.swift; sourceTree = ""; };
11D6C0E62EE22C0F006017F0 /* R.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = R.swift; sourceTree = ""; };
11D6C0EA2EE22C69006017F0 /* Ruby.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Ruby.swift; sourceTree = ""; };
11D6C0EE2EE22CB8006017F0 /* Matlab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Matlab.swift; sourceTree = ""; };
11D6C0F22EE22D39006017F0 /* Dart.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Dart.swift; sourceTree = ""; };
11D6C0F62EE22D73006017F0 /* Vb.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Vb.swift; sourceTree = ""; };
11D6C0FA2EE22DFC006017F0 /* Assembly.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Assembly.swift; sourceTree = ""; };
11D6C0FE2EE22E48006017F0 /* Scratch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Scratch.swift; sourceTree = ""; };
11D6C1022EE22E8B006017F0 /* Groovy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Groovy.swift; sourceTree = ""; };
11D6C1062EE22EE8006017F0 /* ObjectiveC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ObjectiveC.swift; sourceTree = ""; };
11D702A52E5ADDE2004DBAEC /* LayoutManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LayoutManager.swift; sourceTree = ""; };
11D702AB2E5B8E02004DBAEC /* HtmlExtractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HtmlExtractor.swift; sourceTree = ""; };
11D943192E643EF20010CC2B /* JavaScript.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JavaScript.swift; sourceTree = ""; };
11D9431D2E643F1F0010CC2B /* Swift.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Swift.swift; sourceTree = ""; };
11D943212E643F3B0010CC2B /* Php.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Php.swift; sourceTree = ""; };
11D943262E643F5E0010CC2B /* GitHubLight.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GitHubLight.swift; sourceTree = ""; };
11F018AB2EF7E77B00F07580 /* MPreviewFindPanel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPreviewFindPanel.swift; sourceTree = ""; };
11F018B12EF8415200F07580 /* MPreviewContainerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPreviewContainerView.swift; sourceTree = ""; };
11F177192EF1E92C00CC566F /* ViewController+Menu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ViewController+Menu.swift"; sourceTree = ""; };
11F2D4F32F1042F4002E4E47 /* Project+Date.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Project+Date.swift"; sourceTree = ""; };
11F389552EEA108C0008EC18 /* Mermaid.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Mermaid.swift; sourceTree = ""; };
11F43F3A2F127C6900652350 /* Meet FSNotes 7.textbundle */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = "Meet FSNotes 7.textbundle"; sourceTree = ""; };
11F5D53A2EFDA17000A66466 /* modern.icon */ = {isa = PBXFileReference; lastKnownFileType = folder.iconcomposer.icon; path = modern.icon; sourceTree = ""; };
15136766333878E10A6B0457 /* Pods_FSNotes__Notarized_.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_FSNotes__Notarized_.framework; sourceTree = BUILT_PRODUCTS_DIR; };
275592961F3AE9B5006B8988 /* MainWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainWindowController.swift; sourceTree = ""; };
2799407B218484C900727B20 /* TitleBarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TitleBarView.swift; sourceTree = ""; };
365935BA74CEA7B5CAFAB536 /* Pods-FSNotes.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FSNotes.debug.xcconfig"; path = "Target Support Files/Pods-FSNotes/Pods-FSNotes.debug.xcconfig"; sourceTree = ""; };
42E001C52ADAC2930099E7AD /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = ""; };
42E001C92ADAC2930099E7AD /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = ""; };
42E001CB2ADAC2930099E7AD /* InfoPlist.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = InfoPlist.xcstrings; sourceTree = ""; };
42E001CD2ADAC2930099E7AD /* mul */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; name = mul; path = mul.lproj/Main.xcstrings; sourceTree = ""; };
42E001CE2ADAC2930099E7AD /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = ""; };
4796D64E77383E6A5A3F900B /* Pods-FSNotes iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FSNotes iOS.release.xcconfig"; path = "Target Support Files/Pods-FSNotes iOS/Pods-FSNotes iOS.release.xcconfig"; sourceTree = ""; };
484D580095FCD450AE46554D /* Pods-FSNotes iOS Share Extension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FSNotes iOS Share Extension.debug.xcconfig"; path = "Target Support Files/Pods-FSNotes iOS Share Extension/Pods-FSNotes iOS Share Extension.debug.xcconfig"; sourceTree = ""; };
6066605B9BAF43A4BF3B60C1 /* Pods_FSNotes__iCloud_.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_FSNotes__iCloud_.framework; sourceTree = BUILT_PRODUCTS_DIR; };
62E7ACC8B47FFD05898BD354 /* Pods-FSNotes (iCloud).debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FSNotes (iCloud).debug.xcconfig"; path = "Target Support Files/Pods-FSNotes (iCloud)/Pods-FSNotes (iCloud).debug.xcconfig"; sourceTree = ""; };
6ED8B562C4824136E3D33EDC /* Pods-FSNotesCore macOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FSNotesCore macOS.debug.xcconfig"; path = "Target Support Files/Pods-FSNotesCore macOS/Pods-FSNotesCore macOS.debug.xcconfig"; sourceTree = ""; };
6F13BB2820FEDE230005E120 /* DateFormatter+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DateFormatter+.swift"; sourceTree = ""; };
6F13BB2920FEDE230005E120 /* String+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+.swift"; sourceTree = ""; };
6F13BB2A20FEDE230005E120 /* URL+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URL+.swift"; sourceTree = ""; };
6F13BB3820FEDE230005E120 /* UserDataService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDataService.swift; sourceTree = ""; };
747C0F2A42B8190F5AC0ECDB /* Pods-FSNotes (iCloud Documents).debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FSNotes (iCloud Documents).debug.xcconfig"; path = "Target Support Files/Pods-FSNotes (iCloud Documents)/Pods-FSNotes (iCloud Documents).debug.xcconfig"; sourceTree = ""; };
781ADC8297B1AC61D8E278F6 /* Pods-FSNotes iOS Share Extension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FSNotes iOS Share Extension.release.xcconfig"; path = "Target Support Files/Pods-FSNotes iOS Share Extension/Pods-FSNotes iOS Share Extension.release.xcconfig"; sourceTree = ""; };
85B72F46887638CA9CC70D39 /* Pods_FSNotes_iOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_FSNotes_iOS.framework; sourceTree = BUILT_PRODUCTS_DIR; };
8F7136ED23490CBF004DFA6E /* Markdown.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Markdown.swift; sourceTree = ""; };
9381D32FA909CAB6102C4A5C /* Pods-FSNotes (Notarized).debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FSNotes (Notarized).debug.xcconfig"; path = "Target Support Files/Pods-FSNotes (Notarized)/Pods-FSNotes (Notarized).debug.xcconfig"; sourceTree = ""; };
99068B82274CF88F23C4761D /* Pods_FSNotes_iOS_Share_Extension.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_FSNotes_iOS_Share_Extension.framework; sourceTree = BUILT_PRODUCTS_DIR; };
9EA62EEDB6BE9BF8727E66E0 /* Pods-FSNotes.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FSNotes.release.xcconfig"; path = "Target Support Files/Pods-FSNotes/Pods-FSNotes.release.xcconfig"; sourceTree = ""; };
A0C1E679E6D0B408CAC6372D /* Pods-FSNotesCore macOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FSNotesCore macOS.release.xcconfig"; path = "Target Support Files/Pods-FSNotesCore macOS/Pods-FSNotesCore macOS.release.xcconfig"; sourceTree = ""; };
B3A8E91DD978BBA557F778F9 /* Pods_FSNotesCore_macOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_FSNotesCore_macOS.framework; sourceTree = BUILT_PRODUCTS_DIR; };
C1E2B9BF60C418804784CC3B /* Pods-FSNotes (Notarized).release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FSNotes (Notarized).release.xcconfig"; path = "Target Support Files/Pods-FSNotes (Notarized)/Pods-FSNotes (Notarized).release.xcconfig"; sourceTree = ""; };
C8E92DD65B370BD263427B83 /* Pods-FSNotes (iCloud Documents).release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FSNotes (iCloud Documents).release.xcconfig"; path = "Target Support Files/Pods-FSNotes (iCloud Documents)/Pods-FSNotes (iCloud Documents).release.xcconfig"; sourceTree = ""; };
D7013DFF26C3B116006F58E3 /* NSColor+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSColor+.swift"; sourceTree = ""; };
D7038E2520FB24E000A54E69 /* NoteAttachment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoteAttachment.swift; sourceTree = ""; };
D7063969202230BB00BC8446 /* EditorViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditorViewController.swift; sourceTree = ""; };
D70716DB2307E82900B44B0D /* SingleImageTouchDownGestureRecognizer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleImageTouchDownGestureRecognizer.swift; sourceTree = ""; };
D708AC662000EF5800A1760F /* NoteType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoteType.swift; sourceTree = ""; };
D709C9E129AFD9E0006EF9A8 /* GitTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GitTableViewCell.swift; sourceTree = ""; };
D70B1FAA29213EDF003923DC /* HyperlinkTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HyperlinkTextField.swift; sourceTree = ""; };
D7104A63230BD8C500B6D8EE /* SortDirection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SortDirection.swift; sourceTree = ""; };
D71354032042AFC800E3776F /* SettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewController.swift; sourceTree = ""; };
D714496120C72D3400D7AD46 /* UIImage+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+.swift"; sourceTree = ""; };
D714749A279CE8EE001A8B29 /* MainNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainNavigationController.swift; sourceTree = ""; };
D714749C279D7DBC001A8B29 /* SearchQuery.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchQuery.swift; sourceTree = ""; };
D7153DFC2285A93300A2C20F /* AboutWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutWindowController.swift; sourceTree = ""; };
D7153E042285C09C00A2C20F /* AboutViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutViewController.swift; sourceTree = ""; };
D7153E082285EC6100A2C20F /* TitleTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TitleTextField.swift; sourceTree = ""; };
D7163D2E24E81B5C00B1FC05 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = ""; };
D7163D3324E81D9900B1FC05 /* MainInterface.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = MainInterface.storyboard; sourceTree = ""; };
D7170C1C20F8565B001DDB36 /* FileSystemEventManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileSystemEventManager.swift; sourceTree = ""; };
D71AA0212143A4A8004AFD2A /* MoveViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoveViewController.swift; sourceTree = ""; };
D71B9D792867027000D2F323 /* NoteViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoteViewController.swift; sourceTree = ""; };
D71B9D812868658100D2F323 /* EditorViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditorViewController.swift; sourceTree = ""; };
D71B9D852868BF7F00D2F323 /* TextStorageProcessor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextStorageProcessor.swift; sourceTree = ""; };
D71C4A4D1F520F0E00EBA30B /* MPreview.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = MPreview.bundle; sourceTree = ""; };
D71FD2242101CFD0008BEFA1 /* UITextView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITextView+.swift"; sourceTree = ""; };
D720240922A9412B000A7691 /* Markdown.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = Markdown.icns; sourceTree = ""; };
D720240A22A9412B000A7691 /* Text.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = Text.icns; sourceTree = ""; };
D720240B22A9412B000A7691 /* TextBundle.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = TextBundle.icns; sourceTree = ""; };
D720241822A941A3000A7691 /* EncryptedTextPack.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = EncryptedTextPack.icns; sourceTree = ""; };
D72682A929BE8E1F00F6E961 /* RepositoryAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RepositoryAction.swift; sourceTree = ""; };
D726DE89287ACC1E00F8406C /* NSWindow+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSWindow+.swift"; sourceTree = ""; };
D72DAF0729B27D75001243BB /* ProjectSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProjectSettings.swift; sourceTree = ""; };
D72E05861F5220D300977D02 /* Down.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Down.framework; sourceTree = ""; };
D730829123084340003185D1 /* MPreviewView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPreviewView.swift; sourceTree = ""; };
D730BD26222BF30700E69C93 /* KeychainConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainConfiguration.swift; sourceTree = ""; };
D730BD29222BF32A00E69C93 /* KeychainPasswordItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainPasswordItem.swift; sourceTree = ""; };
D730BD2D222DABA100E69C93 /* NoteContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoteContainer.swift; sourceTree = ""; };
D730BD34222DB11E00E69C93 /* TextBundleInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextBundleInfo.swift; sourceTree = ""; };
D730BD3B222DB9FC00E69C93 /* NameHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NameHelper.swift; sourceTree = ""; };
D730BD59223BFEB200E69C93 /* RuntimeError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuntimeError.swift; sourceTree = ""; };
D7315ECE215ECF3000AB49D4 /* EditorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditorView.swift; sourceTree = ""; };
D7315ED1215ED15500AB49D4 /* SidebarSplitView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarSplitView.swift; sourceTree = ""; };
D7315ED4215ED95600AB49D4 /* NSAppearance+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSAppearance+.swift"; sourceTree = ""; };
D735E5BC1F2EF66000173215 /* NoteCellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoteCellView.swift; sourceTree = ""; };
D735E5BE1F2F001500173215 /* NoteRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoteRowView.swift; sourceTree = ""; };
D73673A720D10CF2000BA61D /* CloudDriveManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CloudDriveManager.swift; sourceTree = ""; };
D736DDA827B5DD370012ED70 /* EditorSelectionRect.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditorSelectionRect.swift; sourceTree = ""; };
D736DDAA27BABFF80012ED70 /* RevisionsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RevisionsViewController.swift; sourceTree = ""; };
D736DDAC27BAC7940012ED70 /* Note+History.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Note+History.swift"; sourceTree = ""; };
D73794C023366F5200E75A28 /* ImageScrollView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageScrollView.swift; sourceTree = ""; };
D738356C2242871400B260DD /* MasterPasswordViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MasterPasswordViewController.swift; sourceTree = ""; };
D73B3134298FBF4400F46144 /* GitViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GitViewController.swift; sourceTree = ""; };
D73BCC5428EB5EBE008B3BBC /* Commit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Commit.swift; sourceTree = ""; };
D73BCC5628EB5EBE008B3BBC /* Branch.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Branch.swift; sourceTree = ""; };
D73BCC5728EB5EBE008B3BBC /* Branches.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Branches.swift; sourceTree = ""; };
D73BCC5828EB5EBE008B3BBC /* BranchesIterator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BranchesIterator.swift; sourceTree = ""; };
D73BCC5A28EB5EBE008B3BBC /* Strings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Strings.swift; sourceTree = ""; };
D73BCC5B28EB5EBE008B3BBC /* ConfigManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConfigManager.swift; sourceTree = ""; };
D73BCC5C28EB5EBE008B3BBC /* Error.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Error.swift; sourceTree = ""; };
D73BCC5D28EB5EBE008B3BBC /* Wrapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Wrapper.swift; sourceTree = ""; };
D73BCC5E28EB5EBE008B3BBC /* Progress.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Progress.swift; sourceTree = ""; };
D73BCC5F28EB5EBE008B3BBC /* Blob.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Blob.swift; sourceTree = ""; };
D73BCC6028EB5EBF008B3BBC /* OID.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OID.swift; sourceTree = ""; };
D73BCC6128EB5EBF008B3BBC /* Signature.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Signature.swift; sourceTree = ""; };
D73BCC6228EB5EBF008B3BBC /* Object.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Object.swift; sourceTree = ""; };
D73BCC6428EB5EBF008B3BBC /* TagIterator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TagIterator.swift; sourceTree = ""; };
D73BCC6528EB5EBF008B3BBC /* Tags.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Tags.swift; sourceTree = ""; };
D73BCC6628EB5EBF008B3BBC /* Tag.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Tag.swift; sourceTree = ""; };
D73BCC6828EB5EBF008B3BBC /* RevisionIterator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RevisionIterator.swift; sourceTree = ""; };
D73BCC6928EB5EBF008B3BBC /* FileHistoryIterator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileHistoryIterator.swift; sourceTree = ""; };
D73BCC6B28EB5EC0008B3BBC /* DiffEntry.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DiffEntry.swift; sourceTree = ""; };
D73BCC6C28EB5EC0008B3BBC /* Diff.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Diff.swift; sourceTree = ""; };
D73BCC6E28EB5EC0008B3BBC /* KeyAuthentication.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyAuthentication.swift; sourceTree = ""; };
D73BCC6F28EB5EC0008B3BBC /* Authentication.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Authentication.swift; sourceTree = ""; };
D73BCC7028EB5EC0008B3BBC /* PasswordAuthentication.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PasswordAuthentication.swift; sourceTree = ""; };
D73BCC7228EB5EC0008B3BBC /* Remote.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Remote.swift; sourceTree = ""; };
D73BCC7328EB5EC0008B3BBC /* Remotes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Remotes.swift; sourceTree = ""; };
D73BCC7528EB5EC1008B3BBC /* Statuses.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Statuses.swift; sourceTree = ""; };
D73BCC7628EB5EC1008B3BBC /* Status.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Status.swift; sourceTree = ""; };
D73BCC7728EB5EC1008B3BBC /* StatusIterator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatusIterator.swift; sourceTree = ""; };
D73BCC7928EB5EC1008B3BBC /* Index.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Index.swift; sourceTree = ""; };
D73BCC7A28EB5EC1008B3BBC /* Index+Commit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Index+Commit.swift"; sourceTree = ""; };
D73BCC7B28EB5EC1008B3BBC /* Index+Files.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Index+Files.swift"; sourceTree = ""; };
D73BCC7D28EB5EC2008B3BBC /* Head+Checkout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Head+Checkout.swift"; sourceTree = ""; };
D73BCC7E28EB5EC2008B3BBC /* Head.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Head.swift; sourceTree = ""; };
D73BCC7F28EB5EC2008B3BBC /* Head+Merge.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Head+Merge.swift"; sourceTree = ""; };
D73BCC8128EB5EC2008B3BBC /* TreeEntry.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TreeEntry.swift; sourceTree = ""; };
D73BCC8228EB5EC2008B3BBC /* Tree.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Tree.swift; sourceTree = ""; };
D73BCC8428EB5EC3008B3BBC /* RepositoryManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RepositoryManager.swift; sourceTree = ""; };
D73BCC8528EB5EC3008B3BBC /* Repository.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Repository.swift; sourceTree = ""; };
D73BCC8628EB5EC3008B3BBC /* Repository+Open.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Repository+Open.swift"; sourceTree = ""; };
D73BCC8728EB5EC3008B3BBC /* Repository+Lookup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Repository+Lookup.swift"; sourceTree = ""; };
D73BCC8828EB5EC3008B3BBC /* Repository+Commit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Repository+Commit.swift"; sourceTree = ""; };
D73BCC8A28EB5EC3008B3BBC /* Reference.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Reference.swift; sourceTree = ""; };
D73BCC8B28EB5EC3008B3BBC /* Reference+Target.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Reference+Target.swift"; sourceTree = ""; };
D73FAE9E21553CAA0058BE61 /* UIApplication+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIApplication+.swift"; sourceTree = ""; };
D74112271FABA21B00AB619A /* MainWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainWindow.swift; sourceTree = ""; };
D7465F27207F2CD600E46A52 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
D7470D062170E890006B2A92 /* NSTextStorage++.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSTextStorage++.swift"; sourceTree = ""; };
D7487FD5217389F800D09383 /* NSImage+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSImage+.swift"; sourceTree = ""; };
D7487FE82174E5CB00D09383 /* NSAttributedStringKey+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSAttributedStringKey+.swift"; sourceTree = ""; };
D74922111FACE9B100C45108 /* Down.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Down.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D74B7B642137D3A1007F5331 /* AttributedBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributedBox.swift; sourceTree = ""; };
D74B7B682137EFA9007F5331 /* SingleTouchDownGestureRecognizer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleTouchDownGestureRecognizer.swift; sourceTree = ""; };
D74D479E256DF2EB00D97647 /* FSNTextAttachmentCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FSNTextAttachmentCell.swift; sourceTree = ""; };
D7508FC71F337E850047AB76 /* SearchTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchTextField.swift; sourceTree = ""; };
D7508FCD1F3438540047AB76 /* PrefsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrefsViewController.swift; sourceTree = ""; };
D752D80723454750006842F9 /* NSTextAttachment+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSTextAttachment+.swift"; sourceTree = ""; };
D75627CD26D1165A000AF6EA /* ImageFormat.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageFormat.swift; sourceTree = ""; };
D75629B027D4DB7E00F55588 /* CodeFontViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CodeFontViewController.swift; sourceTree = ""; };
D75629B227D4DE9F00F55588 /* CodeThemeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CodeThemeViewController.swift; sourceTree = ""; };
D75629B427D5036D00F55588 /* SortByViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SortByViewController.swift; sourceTree = ""; };
D75629B627D53EB100F55588 /* ThanksViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThanksViewController.swift; sourceTree = ""; };
D75A34E427D7CD440085438F /* SidebarViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarViewController.swift; sourceTree = ""; };
D75EE7F62078B22D0055F159 /* SidebarItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarItem.swift; sourceTree = ""; };
D75EE7F92078B3C00055F159 /* Sidebar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sidebar.swift; sourceTree = ""; };
D75EE7FC2078C5460055F159 /* SidebarCellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarCellView.swift; sourceTree = ""; };
D75EE7FF2078E0C60055F159 /* SidebarItemType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarItemType.swift; sourceTree = ""; };
D75F3336205EC34800CC887E /* FSNotes iOS Share Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "FSNotes iOS Share Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
D75F3338205EC34800CC887E /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = ""; };
D75F333D205EC34800CC887E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
D75F3344205ECE8900CC887E /* FSNotes iOS Share.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "FSNotes iOS Share.entitlements"; sourceTree = ""; };
D76025B1204EEF64000B9F59 /* TextFormatter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextFormatter.swift; sourceTree = ""; };
D76447DB1F3A4F0700965F01 /* UserDefaultsManagement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultsManagement.swift; sourceTree = ""; };
D7679375201F0BFD000F7BBF /* SortBy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SortBy.swift; sourceTree = ""; };
D7679386201F21F5000F7BBF /* FSNotes iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "FSNotes iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
D7679388201F21F5000F7BBF /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "