GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Setting to disable DFU and FS access by DavisNT · Pull Request #1891 · InfiniTimeOrg/InfiniTime

Conversation

@DavisNT

@DavisNT DavisNT commented Oct 20, 2023 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

This PR adds setting to disable firmware update and Bluetooth file transfer.
This is 2. part for #1814 (comment)

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@github-actions

github-actions Bot commented Oct 20, 2023 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

Build size and comparison to main:

Section Size Difference
text 380132B 928B
data 944B 0B
bss 22544B 8B

Run in InfiniEmu

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@DavisNT
DavisNT force-pushed the otaset branch from 46f4e19 to 82464ad Compare October 21, 2023 21:29
@DavisNT DavisNT mentioned this pull request Oct 21, 2023
Adjust NimbleController for changes in InfiniTime InfiniTimeOrg/InfiniSim#125
Closed
@DavisNT

DavisNT commented Oct 21, 2023

Copy link
Copy Markdown
Contributor Author

Both issues discovered by the workflows should now be fixed.

  • I have force-pushed fix for the formatting error in SettingOTA.cpp.
  • For InfiniSim I have created Adjust NimbleController for changes in InfiniTime InfiniSim#125 Building this PR with InfiniSim PR should fix the InfiniSim build issue.
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@DavisNT

DavisNT commented Oct 22, 2023

Copy link
Copy Markdown
Contributor Author

The build-simulator step is expected to fail, because it needs InfiniTimeOrg/InfiniSim#125

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@DavisNT
DavisNT force-pushed the otaset branch from 82464ad to 813488a Compare October 27, 2023 22:08
@DavisNT

DavisNT commented Oct 27, 2023

Copy link
Copy Markdown
Contributor Author

Made two improvements:

  • Added branch prediction hints, to minimize performance impact during real data transfer
  • Return BLE_ATT_ERR_INSUFFICIENT_RES when access is not allowed

Could it be possible to review this PR?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@DavisNT
DavisNT force-pushed the otaset branch from 813488a to ee8b35b Compare October 27, 2023 22:15
@DavisNT

DavisNT commented Oct 27, 2023

Copy link
Copy Markdown
Contributor Author

Rebased as well.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@DavisNT DavisNT mentioned this pull request May 22, 2024
No pairing is needed to re-flash watch #1814
Closed
1 task done
@DavisNT

DavisNT commented Jun 24, 2024

Copy link
Copy Markdown
Contributor Author

Is this PR (and the other PR described in #1814 (comment) ) welcome?
If I will rebase and adjust this PR to work with the latest changes, will it be merged?
@JF002, @FintasticMan, @Avamander Any feedback from project maintainers would be appreciated.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@DavisNT
DavisNT force-pushed the otaset branch from ee8b35b to 62874d3 Compare June 30, 2024 17:45
@DavisNT

DavisNT commented Jun 30, 2024 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor Author

Rebased (against main) and adjusted this PR. And done a few tests on my PineTime.

If there are questions about b2e2690 please see branch https://github.com/DavisNT/InfiniTime/tree/otaset-oom - this branch has the memory saving as the last commit (trying to build otaset-oom without last commit should cause the build to fail with /opt/gcc-arm-none-eabi-10.3-2021.10/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld: region RAM overflowed with stack).

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

mark9064
mark9064 reviewed Jul 1, 2024
View reviewed changes

@mark9064 mark9064 left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally looking good to me! Works well on hardware
Few suggestions, feel free to challenge any of them

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

DavisNT reacted with thumbs up emoji
All reactions
  • 👍 1 reaction
Comment thread src/components/ble/DfuService.cpp Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread src/components/ble/DfuService.cpp Outdated

int DfuService::OnServiceData(uint16_t connectionHandle, uint16_t attributeHandle, ble_gatt_access_ctxt* context) {
#ifndef PINETIME_IS_RECOVERY
if (__builtin_expect(systemTask.GetSettings().GetDfuAndFsMode() == Pinetime::Controllers::Settings::DfuAndFsMode::Disabled, 0)) {

@mark9064 mark9064 Jul 1, 2024

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless you've benchmarked this and it makes a noticeable difference, it's probably best to let the compiler decide (drop the expect)

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@DavisNT DavisNT Jul 2, 2024

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Idea was to have minimal performance impact during actual file transfer and firmware update (by instructing compiler that branching should be optimized for the scenario when the condition is false).
However I tested the performance and in both cases it is around 6.65 KB/s from around 1 m distance.
__builtin_expect removed.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@mark9064 mark9064 Jul 2, 2024

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I totally agree with you technically (makes sense to optimise the enabled case), the only reason I pointed this out is that the number of packets per second is never high enough for it to make a big difference (it is easy to forget how fast the CPU is - I'm pretty sure it'd be bottlenecked by the max bandwidth of BLE at about 700kbps) and therefore IMO the "less code wins" rule takes precedence

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

DavisNT reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

@DavisNT DavisNT Jul 3, 2024

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could very well be that CPU is never the bottleneck in this case (I haven't thought much about this).
Maybe the flash memory speed is the bottleneck (as the average firmware transfer speed is around 50-55 kbps - at least for me).

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@mark9064 mark9064 Jul 3, 2024

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The small packet size used for DFU (20 bytes) is probably the biggest factor. Due to the somewhat fragile way DFU is currently implemented, any size that evenly divides 200 bytes is actually acceptable. It would be interesting to see what throughput with 200 byte packets would be, but unfortunately due to a bug with the driver for my laptop's BT chipset I can't test it currently! I need to debug the driver at some point but my kernel skills aren't too sharp...

The flash memory is really fast (>100mbit/s when used properly), it's bottlenecked by the SPI bus for sure (8mbit/s)

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread src/components/ble/DfuService.h Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread src/components/ble/DfuService.h Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread src/components/ble/FSService.h Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread src/displayapp/screens/settings/Settings.h Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread src/components/settings/Settings.h Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread src/components/ble/FSService.cpp Resolved

Uh oh!

There was an error while loading. Please reload this page.

@DavisNT
DavisNT force-pushed the otaset branch from 62874d3 to 565ed00 Compare July 2, 2024 22:12
@mark9064

mark9064 commented Jul 2, 2024

Copy link
Copy Markdown
Member

Regarding b2e2690
So one option is to decrease the heap size a notch so more RAM is free for static alloc. This is going to happen soon anyway as there are very few bytes free
I'm not 100% sure why the original approach was taken, really @JF002 would have to chime in on this. I suspect that it's to ensure that classes only have access to certain controllers etc? The memory savings look good though

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

mark9064
mark9064 approved these changes Jul 2, 2024
View reviewed changes

@mark9064 mark9064 left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM code wise :)

I haven't had the time to properly consider the alternative ideas put forward in #1814 yet so that might end up being a better user interface, but in terms of implementation this looks solid (aside from discussion about the way of accessing controllers)

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

DavisNT reacted with heart emoji
All reactions
  • ❤️ 1 reaction
@DavisNT

DavisNT commented Oct 19, 2024

Copy link
Copy Markdown
Contributor Author

@JF002, @NeroBurner, @FintasticMan, @Avamander Could it be possible to review this PR?
CC: @mark9064

P.S. If I need to rebase this, please let me know!

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

mark9064
mark9064 reviewed Oct 19, 2024
View reviewed changes

@mark9064 mark9064 left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spotted a couple more things on re-review

I think the only questionable thing at the moment is b2e2690 and whether this architecture is a good idea

Other than those bits this is ready to go IMO

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread src/components/settings/Settings.cpp Outdated
if (bufferSettings.version == settingsVersion) {
settings = bufferSettings;
}
if (settings.dfuAndFsMode == DfuAndFsMode::EnabledTillReboot) {

@mark9064 mark9064 Oct 19, 2024

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although it doesn't make too much of a difference, maybe apply this to bufferSettings inside the if clause. That way it's clear that work is being done only when settings are successfully loaded, and it means that settings only gets updated once

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

NeroBurner reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

@DavisNT DavisNT Oct 22, 2024

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mark9064 I would prefer to leave this as it is now. Currently it will fail-secure (set settings.dfuAndFsMode to DfuAndFsMode::Disabled) if something very unexpected happens.

@NeroBurner This is the reason why DfuAndFsMode::EnabledTillReboot should never get restored from the saved settings on reboot.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@mark9064 mark9064 Oct 23, 2024

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry if it was unclear, I'm suggesting you do this

  if (bufferSettings.version == settingsVersion) {
    if (bufferSettings.dfuAndFsMode == DfuAndFsMode::EnabledTillReboot) {
      bufferSettings.dfuAndFsMode = DfuAndFsMode::Disabled;
    }
    settings = bufferSettings;
  }

I believe this does not change how the code behaves at all?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@DavisNT DavisNT Oct 24, 2024

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is exactly the thing I would like to keep as is (unless requested by the maintainers to change it).
If possible I would like to keep this code as it is and keep it at the very end of Settings::LoadSettingsFromFile().

The change you suggest would not change how the code behaves.
However in case of refactoring it would increase the chances of the if (bufferSettings.dfuAndFsMode == DfuAndFsMode::EnabledTillReboot) { to be forgotten or moved to a code path that is not always executed.

Maybe I should add a code comment above if (settings.dfuAndFsMode == DfuAndFsMode::EnabledTillReboot) { telling that this (when needed) switches off DFU and FS access after reboot?
Or, should I make the requested code change + a code comment?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@mark9064 mark9064 Oct 26, 2024 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'd personally prefer the suggested change with a comment explaining that this is needed for firmware+files security to work properly.

Maybe it'd be better to fix this in the data format itself though. What about introducing a new boolean member of Settings.h that's not inside the Settings struct that stores whether DFU+FS is temporarily enabled.
Then GetDfuAndFsMode can compute the correct enum value using the setting+the member, and SetDfuAndFsMode can unpack the state into Disabled,Disabled+member set,Enabled. That way it will be impossible to break when refactoring and we don't need to mess with saving/loading settings

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

DavisNT reacted with heart emoji
All reactions
  • ❤️ 1 reaction

@DavisNT DavisNT Nov 8, 2024

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mark9064 Thanks! Two bool variables (one in settings and the other one outside) sounds like a really good idea, I have implemented it (see the recent push).

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread src/components/ble/ImmediateAlertService.cpp Outdated

NotificationManager::Notification notif;
std::memcpy(notif.message.data(), alertString, strlen(alertString));
std::memcpy(notif.message.data(), alertString, strlen(alertString) + 1);

@mark9064 mark9064 Oct 19, 2024

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this change related to this patchset? Or is it an unrelated bug fix

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@DavisNT DavisNT Oct 19, 2024

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is unrelated fix.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@NeroBurner NeroBurner Oct 19, 2024

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you open a separate PR for the fix with a nice explanation what is fixed here please 🙏

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

DavisNT reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

@FintasticMan FintasticMan Oct 19, 2024

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's to do with the fact that we don't use the notification buffer optimally (or even correctly really). I've proposed fixes for this in #1694 and #1695, but I haven't followed up on them.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@DavisNT DavisNT Oct 22, 2024

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@NeroBurner Sure! I will make a separate PR for this.
@FintasticMan I think when copying a string using memcpy() the size always needs to be strlen() of the string plus 1 for the trailing zero-byte string terminator (unless the destination memory is guaranteed to be prefilled with zero-bytes).

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@DavisNT DavisNT Nov 3, 2024

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@NeroBurner Created the PR #2159

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
NeroBurner
NeroBurner reviewed Oct 19, 2024
View reviewed changes
Comment thread src/components/settings/Settings.h Resolved

Uh oh!

There was an error while loading. Please reload this page.

@DavisNT
DavisNT force-pushed the otaset branch from 565ed00 to b742cfb Compare November 8, 2024 00:23
@DavisNT

DavisNT commented Nov 9, 2024 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor Author

@mark9064 Building the simulator fails on main branch with exactly the same error messages.

@mark9064, @FintasticMan, @NeroBurner, @JF002, @Avamander the updated PR:

  • is rebased
  • the ImmediateAlertService fix has been moved to a separate PR ImmediateAlertService: fix latent bug #2159
  • changing of setting value on loading has been replaced with two separate bool variables - one volatile and one persisted in the settings object (code from Settings::LoadSettingsFromFile() has been removed)
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@DavisNT

DavisNT commented Nov 15, 2024

Copy link
Copy Markdown
Contributor Author

@FintasticMan, @NeroBurner could it be possible to review this PR (and merge it, if it is OK)?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@NeroBurner NeroBurner added the enhancement Enhancement to an existing app/feature label Nov 16, 2024
@NeroBurner NeroBurner added this to the 1.16.0 milestone Nov 16, 2024
@NeroBurner

NeroBurner commented Nov 16, 2024

Copy link
Copy Markdown
Contributor

We are currently in feature freeze for 1.15. I've scheduled your PR to 1.16

DavisNT reacted with heart emoji
All reactions
  • ❤️ 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

DavisNT added 2 commits September 3, 2025 00:27
@DavisNT
Expose SystemTask dependency controllers
ab14a42
Expose NotificationManager and Settings for use by the feature in next commit.

This is a memory efficient way for accessing SystemTask dependencies from
controllers that have SystemTask injected as a dependency.
Looks like each direct dependency injection uses 4 bytes RAM.
As InfiniTime is close to running out of RAM (using 16 more bytes causes build
to fail with "ld: region RAM overflowed with stack") it might be helpful to use
this approach more.
@DavisNT
Add setting to disable DFU and FS access
d1f5900
@DavisNT
DavisNT force-pushed the otaset branch from b742cfb to d1f5900 Compare September 2, 2025 22:46
@DavisNT

DavisNT commented Sep 2, 2025

Copy link
Copy Markdown
Contributor Author

@NeroBurner I have rebased this PR and resolved the merge conflicts.
Can you please review and merge this into 1.16?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

NeroBurner
NeroBurner approved these changes Sep 3, 2025
View reviewed changes

@NeroBurner NeroBurner left a comment

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good! Thanks for the ping!

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

DavisNT reacted with heart emoji
All reactions
  • ❤️ 1 reaction
@NeroBurner
NeroBurner merged commit e03414c into InfiniTimeOrg:main Sep 3, 2025
@DavisNT

DavisNT commented Sep 4, 2025

Copy link
Copy Markdown
Contributor Author

Thank you very much!

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

metaphys pushed a commit to metaphys/InfiniTime that referenced this pull request Mar 30, 2026
@DavisNT @metaphys
Setting to disable DFU and FS access (InfiniTimeOrg#1891)
ce296d8
* Expose SystemTask dependency controllers

Expose NotificationManager and Settings for use by the feature in next commit.

This is a memory efficient way for accessing SystemTask dependencies from
controllers that have SystemTask injected as a dependency.
Looks like each direct dependency injection uses 4 bytes RAM.
As InfiniTime is close to running out of RAM (using 16 more bytes causes build
to fail with "ld: region RAM overflowed with stack") it might be helpful to use
this approach more.

* Add setting to disable DFU and FS access
iakat pushed a commit to iakat/InfiniTime that referenced this pull request Jun 8, 2026
@DavisNT @iakat
Setting to disable DFU and FS access (InfiniTimeOrg#1891)
13fda78
* Expose SystemTask dependency controllers

Expose NotificationManager and Settings for use by the feature in next commit.

This is a memory efficient way for accessing SystemTask dependencies from
controllers that have SystemTask injected as a dependency.
Looks like each direct dependency injection uses 4 bytes RAM.
As InfiniTime is close to running out of RAM (using 16 more bytes causes build
to fail with "ld: region RAM overflowed with stack") it might be helpful to use
this approach more.

* Add setting to disable DFU and FS access
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@mark9064 mark9064 mark9064 approved these changes
@FintasticMan FintasticMan FintasticMan left review comments
@NeroBurner NeroBurner NeroBurner approved these changes

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

enhancement Enhancement to an existing app/feature

Projects

None yet

Milestone

1.16.0

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

4 participants

@DavisNT @mark9064 @NeroBurner @FintasticMan
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.